LightOJ1026-Critical Links-tarjan

来源:互联网 发布:java内存泄露代码 编辑:程序博客网 时间:2024/05/16 23:43

题目大意:给你一张无向图,让你求桥的个数有多少个,桥就是一张连通图如果把某条边去掉,这张图就变成了两张;

题目解析:用tarjan算法,其中dfn[i]表示dfs时到第i个点的时候的时间标号(从0开始),low[i]表示第i个点能追溯到dfn最小的那个点,那么在tarjan枚举的时候,只要low[v]>dfs[u]就是桥了,因为第v个点没有路能够通往u上面的图;

AC代码:

#include<iostream>#include<cstdio>#include<algorithm>#include<cstring>#include<string>#include<vector>using namespace std;const int N=10010;const int M=100010;vector<int>vec[N];pair<int,int>edge[M];int low[N],dfn[N],cnt,ans;void tarjan(int u,int father){int i,v;low[u]=dfn[u]=cnt++;for(i=0;i<vec[u].size();i++){v=vec[u][i];if(dfn[v]==-1){tarjan(v,u);low[u]=min(low[u],low[v]);}else if(father!=v)low[u]=min(low[u],dfn[v]);if(low[v]>dfn[u]){if(u>v)edge[ans++]=make_pair(v,u);else edge[ans++]=make_pair(u,v);}}}int main(){int cas,c,i,n,k,u,v,j;scanf("%d",&cas);for(c=1;c<=cas;c++){for(i=0;i<N;i++)vec[i].clear();cnt=0;ans=0;scanf("%d",&n);for(i=0;i<n;i++){scanf("%d (%d)",&u,&k);for(j=0;j<k;j++){scanf("%d",&v);vec[u].push_back(v);}}memset(dfn,-1,sizeof(dfn));memset(low,-1,sizeof(low));for(i=0;i<n;i++){if(dfn[i]==-1){tarjan(i,-1);}} sort(edge,edge+ans);printf("Case %d:\n", c);    printf("%d critical links\n", ans);    for(i=0; i<ans; ++ i)        printf("%d - %d\n", edge[i].first, edge[i].second);}return 0;} 



0 0
原创粉丝点击