zoukankan      html  css  js  c++  java
  • HDU 4738 Caocao's Bridges(双连通分量求桥)

    题目链接

    题目大意

      给一个(或多个)无向图,问是否有办法去掉一条边,使得至少有两个以上的无向图,如果可以问最少花费。

    解题思路

      很明显就是找权值最小的桥,但是如果本来就有多个无向图的话,那就没有必要炸桥了。另外还有一个坑点是,如果得到的桥的最小w为0,那么最至少得派一个人去炸(没人怎么炸桥。。。)。计算边双联通分量的时候,要记得同一条边只能用一次,否则的话,子节点永远可以指向父亲节点就不存在桥了。

    代码

    const int maxn = 1e3+10;
    const int maxm = 1e6+10;
    int h[maxn], cg;
    struct E {
        int to, nex, w;
    } e[maxm<<1];
    void ad(int u, int v, int w) {
        e[cg].to = v;
        e[cg].w = w;
        e[cg].nex = h[u];
        h[u] = cg++;
    }
    int dfn[maxn], low[maxn], dn, minn;
    void tarjan(int u, int fa) {
        dfn[u] = low[u] = ++dn;
        for (int i = h[u]; ~i; i = e[i].nex) {
            if (i==(fa^1)) continue;
            int v = e[i].to;
            if (!dfn[v]) {
                tarjan(v, i);
                low[u] = min(low[u], low[v]);
                if (dfn[u]<low[v]) minn = min(minn, e[i].w);
            }
            else low[u] = min(low[u], dfn[v]);
        }
    }
    int n, m; 
    int main() {
        while(~scanf("%d%d", &n, &m) && (n||m)) {
            cg = dn = 0; NIL(h); minn = INF;
            zero(dfn); zero(low);
            for (int i = 0, u, v, w; i<m; ++i) {
                scanf("%d%d%d", &u, &v, &w);
                ad(u,v,w); ad(v,u,w);
            }
            int cnt = 0;
            for (int i = 1; i<=n; ++i)
                if (!dfn[i]) {
                    tarjan(i, -1); ++cnt;
                }
    	if(cnt != 1) printf("0
    ");
            else if (minn==INF) printf("-1
    ");
    	else printf("%d
    ", !minn?1:minn);
        }
        return 0;
    }
    
  • 相关阅读:
    06 Python字符编码与文件处理
    05 基本数据类型+五大数据类型
    04 Python入门学习-流程控制(if else elif while for)
    《算法导论》学习总结 — XX.第22章 图的基本算法
    Google在KDD2013上关于CTR的一篇论文
    二项堆
    B树、B+树、B*树
    mysql sql语句大全
    红黑树
    《算法导论》学习总结 — 13. 第13章 红黑树(2)
  • 原文地址:https://www.cnblogs.com/shuitiangong/p/12904649.html
Copyright © 2011-2022 走看看