zoukankan      html  css  js  c++  java
  • Codeforces 160D Edges in MST tarjan找桥

    Edges in MST

    在用克鲁斯卡尔求MST的时候, 每个权值的边分为一类, 然后将每类的图建出来, 那些桥就是必须有的, 不是桥就不是必须有。

    #include<bits/stdc++.h>
    #define LL long long
    #define fi first
    #define se second
    #define mk make_pair
    #define PLL pair<LL, LL>
    #define PLI pair<LL, int>
    #define PII pair<int, int>
    #define SZ(x) ((int)x.size())
    #define ull unsigned long long
    
    using namespace std;
    
    const int N = 1e6 + 7;
    const int inf = 0x3f3f3f3f;
    const LL INF = 0x3f3f3f3f3f3f3f3f;
    const int mod = 1e9 + 7;
    const double eps = 1e-8;
    const double PI = acos(-1);
    
    struct Edge {
        int a, b, id, tmp1, tmp2;
    };
    
    int n, m, fa[N], ans[N];
    bool brige[N];
    int dfn[N], low[N], idx;
    vector<Edge> vc[N];
    vector<PII> G[N];
    
    int getRoot(int x) {
        return fa[x] == x ? x : fa[x] = getRoot(fa[x]);
    }
    
    void tarjan(int u, int id) {
        dfn[u] = low[u] = ++idx;
        for(auto& e : G[u]) {
            if(e.se == id) continue;
            if(!dfn[e.fi]) {
                tarjan(e.fi, e.se);
                low[u] = min(low[u], low[e.fi]);
                if(dfn[u] < low[e.fi]) brige[e.se] = true;
            } else low[u] = min(low[u], dfn[e.fi]);
        }
    }
    int main() {
        scanf("%d%d", &n, &m);
        for(int i = 1; i <= n; i++) fa[i] = i;
        for(int i = 1; i <= m; i++) {
            int a, b, w;
            scanf("%d%d%d", &a, &b, &w);
            vc[w].push_back(Edge{a, b, i, 0, 0});
        }
        for(int i = 1; i <= 1000000; i++) {
            if(!SZ(vc[i])) continue;
            idx = 0;
            for(auto& e : vc[i]) {
                e.tmp1 = getRoot(e.a);
                e.tmp2 = getRoot(e.b);
                if(e.tmp1 > e.tmp2) swap(e.tmp1, e.tmp2);
            }
            for(auto& e : vc[i]) {
                if(e.tmp1 == e.tmp2) {
                    ans[e.id] = 3;
                } else {
                    G[e.tmp1].clear();
                    G[e.tmp2].clear();
                    dfn[e.tmp1] = dfn[e.tmp2] = 0;
                }
            }
            for(auto& e : vc[i]) {
                if(e.tmp1 != e.tmp2) {
                    G[e.tmp1].push_back(mk(e.tmp2, e.id));
                    G[e.tmp2].push_back(mk(e.tmp1, e.id));
                }
            }
            for(auto& e : vc[i]) {
                if(e.tmp1 != e.tmp2) {
                    if(!dfn[e.tmp1]) tarjan(e.tmp1, 0);
                    if(!dfn[e.tmp2]) tarjan(e.tmp2, 0);
                }
            }
            for(auto& e : vc[i]) {
                if(e.tmp1 != e.tmp2) {
                    if(brige[e.id]) ans[e.id] = 1;
                    else ans[e.id] = 2;
                }
            }
            for(auto& e : vc[i]) {
                int x = getRoot(e.a);
                int y = getRoot(e.b);
                if(x != y) fa[x] = y;
            }
        }
        for(int i = 1; i <= m; i++) {
            if(ans[i] == 1) puts("any");
            else if(ans[i] == 2) puts("at least one");
            else puts("none");
        }
        return 0;
    }
    
    /*
    */
  • 相关阅读:
    归并排序
    快速排序
    UNION与UNION ALL的区别
    聚集索引和非聚集索引
    设计模式之抽象工厂模式
    list中map 的value值时间排序
    webmvc 拦截器 允许跨域 跨域问题 sessionid不一样
    redis 主从复制 和集群
    maven打包
    bcprov-jdk15on包用于创建CSR(证书请求)
  • 原文地址:https://www.cnblogs.com/CJLHY/p/10452732.html
Copyright © 2011-2022 走看看