/**
* Tarjan算法: 求桥
* 时间复杂度: log(M+N)
* 时间: 2014-08-23
* 参考地址: http://www.cnblogs.com/frog112111/archive/2013/09/18/3329220.html
* 题目大意: 无向边选出一条权值最小的边,使其连通分量增加
**/
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
const int N = 1000 + 10;
int min(int a, int b) { return a > b ? b : a; }
struct Edge {
int v, w, next;
Edge(int _v, int _w, int _next) {
v = _v;
w = _w;
next = _next;
}
Edge(){}
}edges[N*N*2];
int head[N], low[N], dfn[N], vis[N], g, cnt, ans;
void addEdge(int u, int v, int w) {
edges[g] = Edge(v, w, head[u]);
head[u] = g++;
}
void Tarjan(int u, int fa) {
low[u] = dfn[u] = ++cnt;
for(int i = head[u]; i != -1; i = edges[i].next) {
int v = edges[i].v;
if(i == (fa ^ 1)) continue; //一条边只访问一次…… i = (i + 1) ^ 1
if(!dfn[v]) {
Tarjan(v, i);
low[u] = min(low[u], low[v]);
if(low[v] > dfn[u]) {
ans = min(ans, edges[i].w);
}
}
else
low[u] = min(low[u], dfn[v]);
}
}
int dfs(int u) {
int res = 0;
vis[u] = true;
for(int i = head[u]; i != -1; i = edges[i].next) {
int v = edges[i].v;
if(!vis[v]) {
res += dfs(v) + 1;
}
}
return res;
}
int main() {
int n, m, u, v, w;
while(scanf("%d %d", &n, &m)) {
if(n == 0 && m == 0) break;
g = cnt = 0;
memset(head, -1, sizeof(head));
memset(dfn, 0, sizeof(dfn));
memset(vis, false, sizeof(vis));
for(int i = 0; i < m; ++i) {
scanf("%d%d%d", &u, &v, &w);
addEdge(u, v, w);
addEdge(v, u, w);
}
if(dfs(1) + 1 < n) {
printf("0\n");
continue;
}
ans = N * N;
Tarjan(1, -1);
ans = (ans == N * N ? -1 : (ans == 0 ? 1 : ans));
printf("%d\n", ans);
}
return 0;
}
HDU 4738 Caocao's Bridges
最新推荐文章于 2021-02-26 17:30:03 发布