POJ 3694 Tarjan+LCA
阿新 • • 發佈:2019-01-27
一個無向圖 求每增加一條邊後 圖的割邊的個數
#include<algorithm> #include<cstring> #include<cstdio> #include<vector> using namespace std; const int maxn=100007; vector<int> vt[maxn]; int dfn[maxn],low[maxn]; int vis[maxn],father[maxn]; int sum,cnt; bool bridge[maxn]; void tarjan(int u) { dfn[u]=low[u]=++cnt; vis[u]++; int i,v; for(i=0;i<vt[u].size();i++) { v=vt[u][i]; if(!vis[v]) { father[v]=u; tarjan(v); low[u]=min(low[v],low[u]); if(low[v]>dfn[u]) { sum++; bridge[v]=true; } } else if(vis[v]==1&&father[u]!=v) { low[u]=min(low[u],dfn[v]); } } vis[u]++; } void deledge(int u) { if(bridge[u]) { bridge[u]=false; sum--; } } void lca(int u,int v) { while(dfn[u]>dfn[v]) { deledge(u); u=father[u]; } while(dfn[v]>dfn[u]) { deledge(v); v=father[v]; } while(u!=v) { deledge(u); u=father[u]; deledge(v); v=father[v]; } } int main() { int n,m,id=0; while(~scanf("%d%d",&n,&m)) { if(n==0&&m==0) { break; } if(id) { puts(""); } int i,j,u,v; for(i=1;i<=n;i++) { vt[i].clear(); } for(i=0;i<m;i++) { scanf("%d%d",&u,&v); vt[u].push_back(v); vt[v].push_back(u); } memset(vis,0,sizeof(vis)); memset(bridge,0,sizeof(bridge)); sum=cnt=0; for(i=1;i<=n;i++) { if(!vis[i]) { tarjan(i); } } int q; scanf("%d",&q); printf("Case %d:\n",++id); while(q--) { scanf("%d%d",&u,&v); lca(u,v); printf("%d\n",sum); } } return 0; }