题意挺简单的但是有好多细节要处理好,就是让求所有割边最小权值
1)自环
2)如果地图根本不是一个联通图那么我们根本不需要炸,答案就是0
3)如果路上的侍卫是0,那么我们至少需要一个人去被炸, 此时答案是1
4)其他情况就正常来就行,求割边
#include <iostream>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
using namespace std;
#define MAXN 3005
#define MAXE 3000005
#define INF 1000000007
struct Edge
{
int u, v, next, val;
}e[MAXE];
int head[MAXE], cnt, ans;
int dfn[MAXN], low[MAXN], fa[MAXN], dep;
bool bri[MAXE];
void init()
{
memset(head, -1, sizeof(head));
memset(fa, -1, sizeof(fa));
memset(dfn, 0, sizeof(dfn));
memset(bri, 0, sizeof(bri));
dep = 0, cnt = 0;
ans = INF;
}
void Addedge(int uu, int vv, int w)
{
e[cnt].u = uu, e[cnt].v = vv, e[cnt].val = w;
e[cnt].next = head[uu], head[uu] = cnt++;
}
int findfa(int x)
{
if(fa[x] == -1) return x;
return fa[x] = findfa(fa[x]);
}
void unit(int x, int y)
{
int fax = findfa(x);
int fay = findfa(y);
if(fax != fay)
fa[fax] = fay;
}
void dfs( int u, int pre)
{
dfn[u] = low[u] = ++dep;
//cout<<"u"<<" "<<u<<endl;
for(int i = head[u]; i != -1; i = e[i].next)
{
int v = e[i].v;
if(i == (pre^1)) continue;
if(!dfn[v])
{
dfs(v, i);
low[u] = min(low[u], low[v]);
if(low[v] > dfn[u])
ans = min(ans, e[i].val);
}
else
low[u] = min(low[u], dfn[v]);
}
}
void solve( int n, int m)
{
dfs(1, -1);
if(ans == INF)
printf("-1\n");
else
printf("%d\n",ans);
}
int main()
{
int n, m, val, u, v;
while(scanf("%d %d",&n, &m) != EOF &&(n + m))
{
init();
for( int i = 0; i < m; i++)
{
scanf("%d %d %d",&u, &v, &val);
if( u == v) continue;
if(!val) val = 1;
Addedge(u, v, val);
Addedge(v, u, val);
unit(u, v);
}
int i;
for( i = 2; i <= n; i++)
{
if(findfa(i) != findfa(1))
break;
}
if(i <= n)
printf("0\n");
else
solve(n, m);
}
}