http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=737
/*** Uva 796 求桥 题目要求:输出题目中所有的桥,按其所连接的点从小到大的顺序输出 解题思路:tarjan算法,所有树枝边都是桥(dfn[u]<low[v]),利用vector存储一下就可以了 */ #include <stdio.h> #include <string.h> #include <algorithm> #include <iostream> #include <vector> using namespace std; const int maxn=10010; const int maxm=100010; struct note { int v,next; bool cut; }edge[maxm]; int head[maxn],ip; void init() { memset(head,-1,sizeof(head)); ip=0; } void addedge(int u,int v) { edge[ip].v=v,edge[ip].next=head[u],edge[ip].cut=false,head[u]=ip++; } int dfn[maxn],low[maxn],dex; int bridge; int n; void tarjan(int u,int pre) { dfn[u]=low[u]=++dex; for(int i=head[u];i!=-1;i=edge[i].next) { int v=edge[i].v; if(v == pre)continue; if(!dfn[v]) { tarjan(v,u); if(low[u]>low[v])low[u]=low[v]; ///桥 if(low[v]>dfn[u]) { bridge++; edge[i].cut=true; edge[i^1].cut=true; } } else if(low[u]>dfn[v]) low[u]=dfn[v]; } } void solve() { memset(dfn,0,sizeof(dfn)); memset(low,0,sizeof(low)); dex=0,bridge=0; for(int i=1;i<=n;i++) { if(!dfn[i]) tarjan(i,i); } printf("%d critical links\n",bridge); vector<pair<int,int> >ans; for(int u=1;u<=n;u++) { for(int i=head[u];i!=-1;i=edge[i].next) { if(edge[i].cut&&edge[i].v>u) { ans.push_back(make_pair(u,edge[i].v)); } } } sort(ans.begin(),ans.end()); for(int i=0;i<ans.size();i++) { printf("%d - %d\n",ans[i].first-1,ans[i].second-1); } printf("\n"); } int main() { while(~scanf("%d",&n)) { init(); for(int i=0;i<n;i++) { int u,num; scanf("%d (%d)",&u,&num); u++; while(num--) { int v; scanf("%d",&v); v++; if(v<=u)continue; addedge(u,v); addedge(v,u); } } solve(); } return 0; }