题意:求加入一条边后剩余的桥。
题解:加入的边形成的环里的桥都不存在了。
#pragma comment(linker, "/STACK:10240000000000,10240000000000") #include <iostream> #include <vector> #include <stack> #include <cstdio> #include <cstring> using namespace std; const int maxn=110009; const int M=210005; int low[maxn]; int dfn[maxn]; int n,m; vector<int>p[maxn]; stack<int>s; int aa,bb; int qu; int vis[maxn]; int fa[maxn]; int b[maxn]; int tmp=1; int ecnt; struct Node { int u,v,next; } edge[maxn*10]; int head[maxn]; int cnt; void init() { tmp=1; for(int i=1; i<=n; i++) fa[i]=i; memset(b,0,sizeof(b)); memset(vis,0,sizeof(vis)); cnt=1; ecnt=0; memset(head,-1,sizeof(head)); } void addedge(int u,int v) { if(u==v)return; edge[ecnt].u = u; edge[ecnt].v = v; edge[ecnt].next = head[u]; head[u] = ecnt++; } int tp; int cur[maxn]; int st[maxn*10]; /*void tarjan(int u) { visit[u]=1; dfn[u]=low[u]=tmp++; for(int i=0; i<p[u].size(); i++) { int v=p[u][i]; if(!visit[v]) { fa[v]=u; tarjan(v); low[u]=min(low[u],low[v]); if(low[v]>dfn[u]) { cnt++; b[v]=1; } } else if(v != fa[u] && visit[v]) { low[u]=min(low[u],dfn[v]); } } } */ void tarjan() { for(int i = 1; i < maxn; ++ i) cur[i] = head[i]; st[++tp] = 1; while(tp) { int k = st[tp]; if(!vis[k]) { dfn[k] = low[k] = tmp++; vis[k] = 1; } for(; cur[k]!=-1; cur[k]=edge[cur[k]].next) { int v = edge[cur[k]].v; if(!vis[v]) { fa[v] = k; break; } else if(vis[v]==1&&v!=fa[k]) low[k]=min(dfn[v],low[k]); } if((cur[k]==-1)&&tp>1) { low[st[tp-1]] = min(low[k],low[st[tp-1]]); if(low[k]>dfn[st[tp-1]]) { b[k] = 1; cnt++; } } if(cur[k]==-1) { vis[k] = 2; tp--; } else st[++tp] = edge[cur[k]].v; } } void LCA(int u,int v) { while(dfn[u]>dfn[v]) { if(b[u]) { cnt--; b[u]=0; } u=fa[u]; } while(dfn[v]>dfn[u]) { if(b[v]) { cnt--; b[v]=0; } v=fa[v]; } while(v!=u) { if(b[u]) { cnt--; b[u] = 0; } if(b[v]) { cnt--; b[v] = 0; } u = fa[u]; v = fa[v]; } } int main() { int cas=1; while(scanf("%d%d",&n,&m)!=EOF) { if(!n&&!m)break; init(); for(int i=0; i<m; i++) { scanf("%d%d",&aa,&bb); addedge(aa,bb); addedge(bb,aa); } tarjan(); for(int i=1;i<=n;i++) cout<<"i : "<<i<<" "<<dfn[i]<<endl; cin>>qu; cout<<"Case "<<cas++<<":"<<endl; while(qu--) { scanf("%d%d",&aa,&bb); LCA(aa,bb); printf("%d\n",cnt-1); } cout<<endl; } return 0; }