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;
}

  

 posted on 2013-08-03 00:11  tobec  阅读(205)  评论(0编辑  收藏  举报