题意:给你一张图,求w最小的桥。
http://acm.hdu.edu.cn/showproblem.php?pid=4738
注意:可能不是联通图(先用并查集判断联通),没有人的时候要输出1,没有桥输出-1。
#include <iostream>
#include <stdio.h>
#include <string.h>
#include <algorithm>
#define MAXN 100010
#define MAXM 2000010
using namespace std;
struct Edge
{
int to,next;
int w;
bool cut;
}edge[MAXM];
int n,m;
int head[MAXN],top;
int LOW[MAXN],DFN[MAXN],Index;
int f[MAXN];
void add(int u,int v,int w)
{
edge[top].to=v;
edge[top].next=head[u];
edge[top].cut=false;
edge[top].w=w;
head[u]=top++;
}
void init()
{
Index=0;
memset(head,-1,sizeof(head));
memset(DFN,0,sizeof(DFN));
for(int i=1;i<=n;i++)
f[i]=i;
top=0;
}
void Tarjan(int u,int fa)
{
DFN[u]=LOW[u]=++Index;
int f=1;
for(int i = head[u];i != -1;i = edge[i].next)
{
int v=edge[i].to;
if(v==fa&&f)
{
f=0;
continue;
}
if(!DFN[v])
{
Tarjan(v,u);
LOW[u]=min(LOW[u],LOW[v]);
if(LOW[v]>DFN[u])
{
edge[i].cut=true;
}
}
else if(DFN[v]<DFN[u])
LOW[u]=min(LOW[u],DFN[v]);
}
}
int find(int x)
{
if(f[x]!=x)f[x]=find(f[x]);
return f[x];
}
void Union(int a,int b)
{
int a1=find(a);
int b1=find(b);
if(a1!=b1)
{
f[a1]=b1;
}
}
void solve()
{
for(int i=1;i<=n;i++)
if(!DFN[i])
Tarjan(i,i);
int ans=999999999;
for(int u=1;u<=n;u++)
{
for(int i=head[u];i!=-1;i=edge[i].next)
if(edge[i].cut)
ans=min(ans,edge[i].w);
}
if(ans==999999999)cout<<-1<<endl;
else if(ans==0)cout<<1<<endl;
else cout<<ans<<endl;
}
int main()
{
while(cin>>n>>m&&(n||m))
{
init();
for(int i=0;i<m;i++)
{
int u,v,w;
scanf("%d%d%d",&u,&v,&w);
if(u==v)continue ;
add(u,v,w);
add(v,u,w);
Union(u,v);
}
bool flag=1;
for(int i=1;i<=n;i++)
{
if(find(i)!=find(1))
flag=0;
}
if(flag==0)
cout<<0<<endl;
else
solve();
}
}