题意:给出一个无向图,让你去掉一条边,令这个图不连通,并且令花费最小,去掉一条边的花费必须大于等于这条边的权值。
思路:比较简单的一个求桥的问题吧。但是有两个trick,第一个是如果这个图不连通,那么花费为0,另一个是,如果有一个桥是0,那么结果是1,因为至少要排一个人带炸弹。
代码:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<algorithm>
#include<map>
#include<queue>
#include<stack>
#include<cmath>
#include<vector>
#define inf 0x3f3f3f3f
#define Inf 0x3FFFFFFFFFFFFFFFLL
#define eps 1e-9
#define pi acos(-1.0)
using namespace std;
typedef long long ll;
using namespace std;
const int maxn=1000+10;
const int maxm=1000000+10;
struct Edge
{
int v,w,next;
};
Edge edges[maxm<<1];
int head[maxn],nEdge;
int pre[maxn],dfs_clock,cnt,ans;
int n,m;
void AddEdge(int u,int v,int w)
{
nEdge++;
edges[nEdge].v=v;
edges[nEdge].w=w;
edges[nEdge].next=head[u];
head[u]=nEdge;
}
int tarjan(int u,int fa)
{
int lowu=pre[u]=++dfs_clock;
for(int k=head[u];k!=-1;k=edges[k].next)
{
if(k!=(fa^1))
{
int v=edges[k].v;
if(!pre[v])
{
int lowv=tarjan(v,k);
lowu=min(lowv,lowu);
if(lowv>pre[u])
ans=min(ans,edges[k].w);
}
else if(pre[v]<lowu)
lowu=pre[v];
}
}
return lowu;
}
void find_ebc()
{
dfs_clock=cnt=0;
ans=inf;
memset(pre,0,sizeof(pre));
for(int i=1;i<=n;++i)
if(!pre[i]) tarjan(i,-1),cnt++;
}
int main()
{
//freopen("in.txt","r",stdin);
//freopen("out.txt","w",stdout);
while(~scanf("%d%d",&n,&m))
{
if(n==0&&m==0) break;
memset(head,0xff,sizeof(head));
nEdge=-1;
int u,v,w;
for(int i=0;i<m;++i)
{
scanf("%d%d%d",&u,&v,&w);
AddEdge(u,v,w);
AddEdge(v,u,w);
}
find_ebc();
if(cnt>1)
ans=0;
else if(ans==0) ans=1;
if(ans==inf)
printf("-1\n");
else printf("%d\n",ans);
}
return 0;
}