HDU 4738 Caocao's Bridges

来源:互联网 发布:马克威算法 编辑:程序博客网 时间:2024/05/16 16:05
/***  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;}

0 0
原创粉丝点击