重连通分量的求解
1 // time 32ms 2 #include <iostream> 3 #include <cstdio> 4 #include <cstring> 5 #include <cmath> 6 #include <algorithm> 7 #include <string> 8 #include <vector> 9 #include <set> 10 #include <map> 11 #include <stack> 12 #include <queue> 13 #include <sstream> 14 #include <iomanip> 15 using namespace std; 16 typedef long long LL; 17 const int INF = 0x4fffffff; 18 const double EXP = 1e-5; 19 const int MS = 1005; 20 const int SIZE = 100005; 21 22 struct edge 23 { 24 int u,v; 25 void output() 26 { 27 printf("%d---%d",u,v); 28 } 29 int cmp(edge &t) 30 { 31 return ((u==t.u&&v==t.v)||(u==t.v&&v==t.u)); 32 } 33 }; 34 35 edge sta[MS]; 36 int top; 37 int edges[MS][MS]; // 1:连接未入stack,2:连接入过stack 38 int vis[MS]; 39 int n,m; 40 int tdfn; 41 int dfn[MS]; 42 int low[MS]; 43 44 void DFS(int u) 45 { 46 for(int v=1;v<=n;v++) 47 { 48 if(edges[u][v]==1) 49 { 50 edge t; 51 t.u=u;t.v=v;sta[++top]=t; 52 edges[u][v]=edges[v][u]=2; 53 if(!vis[v]) 54 { 55 vis[v]=1; 56 dfn[v]=low[v]=++tdfn; 57 DFS(v); 58 low[u]=min(low[u],low[v]); 59 if(low[v]>=dfn[u]) 60 { 61 bool FirstEdge=true; 62 while(1) 63 { 64 if(top<0) 65 break; 66 if(FirstEdge) 67 FirstEdge=false; 68 else 69 printf(" "); 70 edge t1; 71 t1=sta[top]; 72 t1.output(); 73 sta[top].u=0;sta[top].v=0;//删除top边 74 top--; 75 if(t1.cmp(t)) 76 break; 77 } 78 printf("\n"); 79 } 80 } 81 else 82 low[u]=min(low[u],dfn[v]); 83 } 84 } 85 } 86 87 88 int main() 89 { 90 int i,u,v,number=1; 91 while(1) 92 { 93 scanf("%d%d",&n,&m); 94 if((n+m)==0) 95 break; 96 memset(edges,0,sizeof(edges)); 97 for(int i=1;i<=m;i++) 98 { 99 scanf("%d%d",&u,&v); 100 edges[u][v]=edges[v][u]=1; 101 } 102 if(number++>1) 103 printf("\n"); 104 low[1]=dfn[1]=1; 105 tdfn=1; 106 memset(vis,0,sizeof(vis)); 107 vis[1]=1; 108 memset(sta,0,sizeof(sta)); 109 top=-1; 110 DFS(1); 111 } 112 return 0; 113 }