Codeforces 160D Edges in MST tarjan找桥
在用克鲁斯卡尔求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; } /* */