传送门:http://acm.hdu.edu.cn/showproblem.php?pid=4738
解题思路:
本题比较简单,就是求桥的问题,有几个比较注意的地方
1. 当图连通的时候,派去的士兵的数量为0
2. 当图有桥,且桥上的士兵为0时,派一个人去。
3. 其它情况,选桥上士兵最少的。
4. 注意重边的处理。
实现代码:
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <algorithm> 5 #include <cstdlib> 6 using namespace std; 7 8 const int MAXN=1001; 9 const int MAXM=1001*1001*2; 10 const int INF=1<<30; 11 12 struct Edge{ 13 int to,next; 14 int cnt; 15 bool meg; //标记是否是重边 16 }edges[MAXM]; 17 18 int head[MAXN],tot; 19 void addEdge(int u,int v,int w,bool meg){ 20 edges[tot].to=v; 21 edges[tot].next=head[u]; 22 edges[tot].meg=meg; 23 edges[tot].cnt=w; 24 head[u]=tot++; 25 } 26 27 void init(){ 28 memset(head,-1,sizeof(head)); 29 tot=0; 30 } 31 int DFN[MAXN],LOW[MAXN],Bg[MAXN]; 32 int Index,bridge; 33 34 void Tarjan(int u,int pre,bool meg){ 35 LOW[u]=DFN[u]=++Index; 36 int v; 37 38 for(int i=head[u];i!=-1;i=edges[i].next){ 39 v=edges[i].to; 40 41 if(v==pre&&(!meg)) continue; 42 43 if(!DFN[v]){ 44 Tarjan(v,u,edges[i].meg); 45 46 if(LOW[u]>LOW[v]) 47 LOW[u]=LOW[v]; 48 49 if(LOW[v]>DFN[u]){ 50 Bg[++bridge]=edges[i].cnt; 51 } 52 }else if(LOW[u]>DFN[v]) 53 LOW[u]=DFN[v]; 54 } 55 } 56 57 void solve(int N,int M){ 58 memset(DFN,0,sizeof(DFN)); 59 bridge=Index=0; 60 61 Tarjan(1,1,false); 62 63 if(bridge==0){ 64 printf("-1 "); 65 return; 66 } 67
//判断图是否连通,下面这段代码应该和判断桥==0,交换一下。 68 for(int i=1;i<=N;i++) 69 if(DFN[i]==0){ 70 printf("0 "); 71 return; 72 } 73 74 int ans=INF; 75 76 for(int i=1;i<=bridge;i++) 77 ans=min(ans,Bg[i]); 78 79 if(ans==0) 80 printf("1 ",ans); 81 else printf("%d ",ans); 82 } 83 84 struct NN{ 85 int u,v; 86 int w; 87 bool operator <(const NN &rhs)const{ 88 if(u!=rhs.u) 89 return u<rhs.u; 90 else if(v!=rhs.v) 91 return v<rhs.v; 92 else 93 return w<rhs.w; 94 } 95 }node[MAXM]; 96 97 int main(){ 98 int N,M; 99 while(scanf("%d%d",&N,&M)!=EOF){ 100 if(N==0&&M==0) break; 101 102 init(); 103 for(int i=0;i<M;i++){ 104 int u,v,w; 105 scanf("%d%d%d",&u,&v,&w); 106 if(u==v) continue; 107 if(u<v) swap(u,v); 108 109 node[i].v=v; 110 node[i].u=u; 111 node[i].w=w; 112 } 113 114 sort(node,node+M); 115 116 for(int i=0;i<M;i++){ 117 if(i==0||(node[i].u!=node[i-1].u||node[i].v!=node[i-1].v)){ 118 if(i<M-1&&node[i].u==node[i+1].u&&node[i].v==node[i+1].v){ 119 addEdge(node[i].u,node[i].v,node[i].w,true); 120 addEdge(node[i].v,node[i].u,node[i].w,true); 121 }else{ 122 addEdge(node[i].u,node[i].v,node[i].w,false); 123 addEdge(node[i].v,node[i].u,node[i].w,false); 124 } 125 126 } 127 } 128 solve(N,M); 129 130 131 } 132 }