POJ3694 Network

给出一个无向连通图,问加入边的过程中,桥的个数。

先用tarjan算法求出桥的总数,标记每个桥的终点。

每加入两个顶点,就查询两个顶点的lca,把lca路径上的桥都剪掉~

#include
#include
#include
#include
#include
using namespace std;
const int maxn=1e6+14;
vector<int> g[maxn];
int N,M,x,y;
int low[maxn];
int dfn[maxn];
int q;
int pos[maxn];
int depth[maxn];
int father[maxn];
int bridge[maxn];
int cnt;
int scc;
int ans;
stack<int> st;
void init () {
    fill(low,low+maxn,0);
    fill(dfn,dfn+maxn,0);
    fill(pos,pos+maxn,0);
    fill(depth,depth+maxn,0);
    fill(father,father+maxn,0);
    fill(bridge,bridge+maxn,0);
    for (int i=0;i) g[i].clear();
    while (!st.empty()) st.pop();
    cnt=0;
    scc=0;
    ans=0;
}
void tarjan (int x,int pre) {
    low[x]=dfn[x]=++cnt;
    depth[x]=depth[pre]+1;
    for (int i=0;i) {
        if (g[x][i]==pre) continue;
        if (!low[g[x][i]]) {
            father[g[x][i]]=x;
            tarjan(g[x][i],x);
            low[x]=min(low[x],low[g[x][i]]);
            if (low[g[x][i]]>dfn[x]) {
                ans++;
                bridge[g[x][i]]=1;
            }
        }
        else if (!pos[g[x][i]]) low[x]=min(low[x],dfn[g[x][i]]);
    }
}
void lca (int u,int v) {
    while (depth[u]<depth[v]) {
        if (bridge[v]) {
            bridge[v]=0;
            ans--;
        }
        v=father[v];
    }
    while (depth[u]>depth[v]) {
        if (bridge[u]) {
            bridge[u]=0;
            ans--;
        }
        u=father[u];
    }
    while (u!=v) {
        if (bridge[u]) {
            bridge[u]=0;
            ans--;
        }
        if (bridge[v]) {
            bridge[v]=0;
            ans--;
        }
        u=father[u];
        v=father[v];
    }
}
int main () {
    int t=1;
    while (~scanf("%d %d",&N,&M)) {
        if (N==0&&M==0) break;
        init ();
        for (int i=0;i) {
            scanf ("%d %d",&x,&y);
            g[x].push_back(y);
            g[y].push_back(x);
        }
        for (int i=1;i<=N;i++) 
        if (!low[i]) tarjan(i,i);
        scanf("%d",&q);
        printf ("Case %d:\n",t++);
        while (q--) {
            scanf ("%d %d",&x,&y);
            lca (x,y);
            printf ("%d\n",ans);
        }
    }
    return 0;
}

 

你可能感兴趣的:(POJ3694 Network)