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
" , 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
" , idx);
}
return 0;
}