UVA796:利用Tarjan求无向图的割边(桥)
Tarjan求割边和求割点的差异不大
int n,deep,root,cnt; int g[maxn],dfn[maxn],low[maxn]; struct Edge{int t,w,next;}e[maxm]; map<int,map<int,int> > mp; vector<pair<int,int> > bridge;
这里有的变量在上一篇博文中已经介绍过了
我们看到mp映射是用来替代二维数组进行判重的
本来打算换成hash_map但是发现并不好用,这是个必须要补的坑
这里的判重是判断是否有重边,由于权重都是1所以并不需要进行更新边权
由于是使用的邻接表来存的图,所以判重不是很方便
可以先读成邻接矩阵再转存邻接表
bridge就是我们求出来的所有的桥
int tarjan(int u,int fa) { int lowu; lowu=dfn[u]=++deep; for(int tmp=g[u];tmp;tmp=e[tmp].next) { int v=e[tmp].t; if(!dfn[v]) { int lowv=tarjan(v,u); lowu=min(lowu,lowv); if(lowv>dfn[u]) { int from,to;from=u;to=v; if(from>to) swap(from,to); bridge.push_back(make_pair(from,to)); } } else if(v!=fa&&dfn[v]<dfn[u]) lowu=min(lowu,dfn[v]); } low[u]=lowu; return lowu; }
int tarjan(int u,int fa) { int lowu; lowu=dfn[u]=++deep; for(int tmp=g[u];tmp;tmp=e[tmp].next) { int v=e[tmp].t; if(!dfn[v]) { int lowv=tarjan(v,u); lowu=min(lowu,lowv); if(lowv>dfn[u]) { int from,to;from=u;to=v; if(from>to) swap(from,to); bridge.push_back(make_pair(from,to)); } } else if(v!=fa&&dfn[v]<dfn[u]) lowu=min(lowu,dfn[v]); } low[u]=lowu; return lowu; }
int tarjan(int u,int fa) { int lowu; lowu=dfn[u]=++deep; for(int tmp=g[u];tmp;tmp=e[tmp].next) { int v=e[tmp].t; if(!dfn[v]) { int lowv=tarjan(v,u); lowu=min(lowu,lowv); if(lowv>dfn[u]) { int from,to;from=u;to=v; if(from>to) swap(from,to); bridge.push_back(make_pair(from,to)); } } else if(v!=fa&&dfn[v]<dfn[u]) lowu=min(lowu,dfn[v]); } low[u]=lowu; return lowu; }
以上是求割边的Tarjan
最后给出完整实现,题目说了要排序,那就排序吧。把求出来的桥排序
1 #include<cstdio> 2 #include<cstring> 3 #include<vector> 4 #include<map> 5 #include<algorithm> 6 using namespace std; 7 const int maxn=10005; 8 const int maxm=100005; 9 int n,deep,root,cnt; 10 int g[maxn],dfn[maxn],low[maxn]; 11 struct Edge{int t,w,next;}e[maxm]; 12 map<int,map<int,int> > mp; 13 vector<pair<int,int> > bridge; 14 bool cmp(pair<int,int> x,pair<int,int> y) 15 { 16 if(x.first!=y.first) 17 return x.first<y.first; 18 else return x.second<y.second; 19 } 20 void addedge(int u,int v,int w) 21 { 22 if(mp[u][v]==1) return; 23 else {mp[u][v]=1;} 24 e[++cnt].t=v;e[cnt].w=w; 25 e[cnt].next=g[u];g[u]=cnt; 26 } 27 int tarjan(int u,int fa) 28 { 29 int lowu; 30 lowu=dfn[u]=++deep; 31 for(int tmp=g[u];tmp;tmp=e[tmp].next) 32 { 33 int v=e[tmp].t; 34 if(!dfn[v]) 35 { 36 int lowv=tarjan(v,u); 37 lowu=min(lowu,lowv); 38 if(lowv>dfn[u]) 39 { 40 int from,to;from=u;to=v; 41 if(from>to) swap(from,to); 42 bridge.push_back(make_pair(from,to)); 43 } 44 } 45 else if(v!=fa&&dfn[v]<dfn[u]) 46 lowu=min(lowu,dfn[v]); 47 } 48 low[u]=lowu; 49 return lowu; 50 } 51 int main() 52 { 53 while(scanf("%d",&n)==1) 54 { 55 deep=cnt=0; 56 memset(g,0,sizeof(g)); 57 memset(dfn,0,sizeof(dfn)); 58 memset(low,0,sizeof(low)); 59 memset(e,0,sizeof(e)); 60 mp.clear(); 61 bridge.clear(); 62 int u,v,m; 63 for(int i=1;i<=n;i++) 64 { 65 scanf("%d (%d)",&u,&m); 66 for(int j=1;j<=m;j++) 67 scanf("%d",&v),addedge(u,v,1); 68 } 69 for(int i=1;i<=n;i++) 70 if(!dfn[i]) {root=i;tarjan(i,-1);} 71 printf("%d critical links ",bridge.size()); 72 sort(bridge.begin(),bridge.end(),cmp); 73 for(int i=0;i<bridge.size();i++) 74 printf("%d - %d ",bridge[i].first,bridge[i].second); 75 printf(" "); 76 } 77 return 0; 78 }