http://acm.hdu.edu.cn/showproblem.php?pid=4738
求得是边权最小的割边,和求割点类似用tarjin,但要注意的是不能走从父亲过来的那一条边,在割点里那样理解没错但放在求割边就不对了,因为割点一旦被除去相邻的边就都没了。割边却只能除去一条边。当low[v]>dfn[u]说明当前的边是割边,相等的时候不是,因为割去(u,v)之后(u,v)之间还有另外的边存在。
此外如果不是连通图直接输出0,如果答案是0要输出1,因为要有人去炸桥。
1 #include<iostream> 2 #include<cstdio> 3 #include<vector> 4 #include<cstring> 5 using namespace std; 6 #define LL long long 7 #define pb push_back 8 #define pii pair<int,int> 9 #define mp make_pair 10 const int maxn=1010; 11 struct Edge{ 12 int v,w,next; 13 }e[2000200]; 14 int first[maxn],tot; 15 void add(int u,int v,int w){ 16 e[tot].v=v; 17 e[tot].w=w; 18 e[tot].next=first[u]; 19 first[u]=tot++; 20 } 21 int dfn[maxn],low[maxn],root,sum,ans; 22 bool vis[maxn]; 23 void dfs(int u,int last){ 24 dfn[u]=low[u]=sum++; 25 vis[u]=1; 26 int son=0; 27 for(int i=first[u];i!=-1;i=e[i].next){ 28 int v=e[i].v,w=e[i].w; 29 if(i==(1^last)) continue; 30 if(vis[v]){ 31 low[u]=min(low[u],dfn[v]); 32 } 33 else{ 34 dfs(v,i); 35 low[u]=min(low[u],low[v]); 36 if(low[v]>dfn[u]){ 37 ans=min(ans,w); 38 } 39 } 40 } 41 } 42 int main(){ 43 int n,m,i,j,u,v,w; 44 while(cin>>n>>m){ 45 if(n==0&&m==0) break; 46 tot=0; 47 memset(first,-1,sizeof(first)); 48 while(m--){ 49 scanf("%d%d%d",&u,&v,&w); 50 add(u,v,w),add(v,u,w); 51 } 52 sum=0; 53 ans=9999999; 54 memset(vis,0,sizeof(vis)); 55 int p=0; 56 for(i=1;i<=n;++i){ 57 if(!vis[i]){ 58 p++; 59 root=i; 60 dfs(i,-1); 61 } 62 } 63 if(p>1){ 64 cout<<0<<endl; 65 continue; 66 } 67 /*for(i=1;i<=n;++i){ 68 cout<<dfn[i]<<' '<<low[i]<<endl; 69 }*/ 70 if(ans==9999999) ans=-1; 71 if(ans==0)ans=1; 72 cout<<ans<<endl; 73 } 74 return 0; 75 }