http://acm.hdu.edu.cn/showproblem.php?pid=4612
双连通分量 + 树的直径
一样的代码 C++ 交了两遍过的 , 看了网上的第一行 , 手动 设定 栈空间
#pragma comment(linker,"/STACK:102400000,102400000") #include <cstdio> #include <cstring> #include <iostream> #include <algorithm> #include <vector> #include <queue> using namespace std; #define inf (1<<29) const int maxn = 202000 , maxm = 2001000; struct Edge { int v , next; bool vis; Edge () {} Edge (int v,int next) : v(v) , next(next) {vis = false;}; }edge[maxm]; int E , head[maxn]; int n , m; void init() { E = 0; memset(head,-1,sizeof(int)*(n+1)); } void addedge(int u,int v) { edge[E] = Edge (v , head[u]); head[u] = E++; edge[E] = Edge (u , head[v]); head[v] = E++; } int dfn[maxn] , low[maxn] , id[maxn] , stk[maxn]; int idx , cnt , top; void tarjan(int u) { int v; dfn[u] = low[u] = ++ cnt; stk[++top] = u; for(int i=head[u];i!=-1;i=edge[i].next) { if(edge[i].vis) continue; edge[i].vis = edge[i^1].vis = true; v = edge[i].v; if(!dfn[v]) { tarjan(v); low[u] = min(low[u] , low[v]); } else low[u] = min(low[u] , dfn[v]); } if(low[u] == dfn[u]) { idx ++; do { v = stk[top--]; id[v] = idx; }while(u != v); } } vector <int> g[maxn]; void solve() { idx = cnt = top = 0; memset(dfn , 0 , sizeof(dfn)); tarjan(1); for(int i=1;i<=idx;i++) g[i].clear(); for(int u=1;u<=n;u++) { for(int i=head[u];i!=-1;i=edge[i].next) { int v = edge[i].v; if(id[u] != id[v]) { g[ id[u] ] . push_back( id[v] ); g[ id[v] ] . push_back( id[u] ); } } } } int dist[maxn]; bool vis[maxn]; queue <int> q; void spfa(int s) { for(int i=1;i<=idx;i++) dist[i] = inf , vis[i] = false; while(!q.empty()) q.pop(); dist[s] = 0; q.push(s); while(!q.empty()) { int u = q.front(); q.pop(); vis[u] = false; int sz = g[u].size(); for(int i=0;i<sz;i++) { int v = g[u][i]; if(dist[u] + 1 < dist[v]) { dist[v] = dist[u] + 1; if(!vis[v]) { vis[v] = true; q.push(v); } } } } } void solve2() { spfa(1); int s = 1; for(int i=1;i<=idx;i++) if(dist[i] != inf && dist[i] > dist[s]) s = i; spfa(s); int ans = 0; for(int i=1;i<=idx;i++) if(dist[i] != inf && dist[i] > ans) ans = dist[i]; printf("%d\n" , idx - ans - 1); } int main() { while(~scanf("%d%d" , &n , &m) && n + m) { init(); while(m--) { int u , v ; scanf("%d%d" , &u, &v); addedge(u , v); } solve(); solve2(); //printf("idx is %d\n" , idx); } return 0; }