输出桥。
#include<cstdio> #include<cstring> #include<cmath> #include<vector> #include<algorithm> using namespace std; const int maxn = 10000 + 10; const int Maxn = 2 * 100000 + 10; int low[maxn]; int dfn[maxn]; int U[maxn], V[maxn]; struct Edge { int from, to, id, ans; } edge[Maxn]; vector<int>G[maxn]; int N, M; int tmpdfn; int tot; int Start, End; struct ANSS { int first, second; }ANS[Maxn]; void init() { for (int i = 0; i<maxn; i++) G[i].clear(); memset(low, 0, sizeof(low)); memset(dfn, 0, sizeof(dfn)); low[1] = dfn[1] = 1; tmpdfn = 0; tot = 0; } void AddEdge(int u, int v) { edge[tot].from = u; edge[tot].to = v; edge[tot].id = tot; edge[tot].ans = 0; G[u].push_back(tot); tot++; edge[tot].from = v; edge[tot].to = u; edge[tot].id = tot; edge[tot].ans = 0; G[v].push_back(tot); tot++; } int Tarjan(int u, int id) { tmpdfn++; int lowu = dfn[u] = tmpdfn; for (int i = 0; i<G[u].size(); i++) { int B = G[u][i]; if (!dfn[edge[B].to]) { int lowv = Tarjan(edge[B].to, edge[B].id); lowu = min(lowu, lowv); if (lowv >= dfn[u]) { if (lowv>dfn[u]) edge[B].ans = 1; } } else if (dfn[edge[B].to]) { if (edge[B].id / 2 == id / 2) continue; lowu = min(lowu, dfn[edge[B].to]); } } low[u] = lowu; return lowu; } bool cmp(const ANSS&a, const ANSS&b) { if (a.first == b.first) return a.second < b.second; return a.first < b.first; } void Display_Cutting_edge() { int AA = 0; for (int i = 0; i < 2 * M; i++) { if (edge[i].ans) { if (edge[i].from < edge[i].to) { ANS[AA].first = edge[i].from; ANS[AA].second = edge[i].to; } else { ANS[AA].first = edge[i].to; ANS[AA].second = edge[i].from; } AA++; } } printf("%d critical links ", AA); sort(ANS, ANS + AA, cmp); for (int i = 0; i < AA; i++) printf("%d - %d ", ANS[i].first-1, ANS[i].second-1); printf(" "); } int main() { while (~scanf("%d", &N)) { init(); M = 0; for (int i = 1; i <= N; i++) { int from,TTT; scanf("%d (%d)", &from, &TTT); while (TTT--) { int too; scanf("%d", &too); if (from >= too) continue; U[M] = from + 1; V[M] = too + 1; AddEdge(U[M], V[M]); M++; } } Start = 1; End = N; Tarjan(1, -1); for (int i = 2; i <= N; i++) if (!dfn[i]) Tarjan(i, -1); Display_Cutting_edge(); } return 0; }