Sample Input
3 3 1 2 7 2 3 4 3 1 4 3 2 1 2 7 2 3 4 0 0
Sample Output
-1 4题意: n个岛用m条桥连接,要破坏一座桥,使图分开 ;每座桥上有敌方士兵,炸桥的士兵不能少于要敌方士兵 求最少要派多少个士兵,即求割桥。选的割桥中,士兵最少的就是结果;有几种情况:1.当图不联通,为0;2.当图没有割桥,输出-1;3.当要割得桥上士兵为0时,至少也要要派一个人去炸;4.其他。 。#include<cstdio> #include<cstring> #include<iostream> #include<algorithm> using namespace std ; const int N=1100 ; const int M=N*N ; struct node { int ok; int to; int w; int next; }e[M]; int head[N],vist[N]; int dfn[N]; int ans[N]; int father[N]; int dfsn,top,qiao; int n,m,no,k; int find(int x) { return x==father[x]? x:father[x]=find(father[x]) ; } int check() //检查图是否联通 { int cout=0; for(int i = 1 ; i <= n ;i++) { if(father[i]==i) cout++; } if(cout>=2) return 0; if(cout==1) return 1 ; } int judge(int u,int v) { for(int i=head[u];i!=-1;i=e[i].next){ if(e[i].to==v) { e[i].ok=1; return 1; } } return 0; } void add(int u,int v,int j) { if(judge(u,v)) return ; e[top].ok=0; e[top].to=v; e[top].w=j; e[top].next=head[u]; head[u]=top++; } int dfs(int u,int fa) { int lowu,lowv; lowu=dfn[u]=++dfsn; vist[u]=1; for(int i=head[u];i!=-1;i=e[i].next) { int v=e[i].to; if(vist[v]&&v!=fa) lowu=min(lowu,dfn[v]); if(!vist[v]&&v!=fa) { lowv=dfs(v,u); lowu=min(lowu,lowv); if( lowv>dfn[u] && v!=fa && !e[i].ok) { ans[qiao++]=e[i].w; no=1; } } } return lowu; } int main() { int u,v,w; while(~scanf("%d%d",&n,&m)) { if(n==0&&m==0) break; dfsn=qiao=top=0;no=0; memset(e,0,sizeof(e)); memset(head,-1,sizeof(head)); memset(dfn,0,sizeof(dfn)); memset(vist,0,sizeof(vist)); memset(ans,0,sizeof(ans)); for(int i = 1 ; i <= n ; i++) father[i]=i; for(int i=1;i<=m;i++) { scanf("%d %d %d",&u,&v,&w); add(u,v,w); add(v,u,w); int x=find(u); int y=find(v); if(x!=y) father[x]=y; } int flag=check() ; if(flag==0) printf("0\n"); //图不联通 if(flag==1) //图联通 { dfs(1,-1); if(no) //如果有割桥 { sort(ans,ans+qiao); //割桥有很多,选桥上士兵最少的那个 if(ans[0]==0) printf("1\n"); //如果桥上士兵为0,最少也要派一个兵去炸 else cout << ans[0] << endl ; //其他的,输出结果 } else printf("-1\n"); } } return 0; }