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;
}

/*
*/
原文地址:https://www.cnblogs.com/CJLHY/p/10452732.html