无向图有重边的tarjan算法
接收数据是把每条边的权值保存起来
有重边的tarjan算法要判断走重边时的low值
然后找出最小权值的桥
另外三个注意点:
1、原本不是一个强联通图的话,派的人是0
2、如果不存在桥的话,输出-1
3、如果桥的最小权值是0,则至少派一个人去炸桥

#include<stdio.h> #include<string.h> #include<algorithm> using namespace std; const int maxn = 1005; const int maxm = 1005*1005; int n, m; int top, tol, cnt; struct Node { int v; int next; int w; }; Node node[maxm * 2]; int dfn[maxn]; int low[maxn]; int head[maxn]; void init() { tol = top = cnt = 0; memset(dfn, 0, sizeof(dfn)); memset(low, 0, sizeof(low)); memset(node, 0, sizeof(node)); memset(head, -1, sizeof(head)); } void addnode(int u, int v, int w) { node[tol].v = v; node[tol].w = w; node[tol].next = head[u]; head[u] = tol++; } void dfs(int u, int fa) { dfn[u] = low[u] = ++cnt; int cnt = 0; for(int i=head[u]; i!=-1; i=node[i].next) { int v = node[i].v; if(!dfn[v]) { dfs(v, u); low[u] = min(low[u], low[v]); } else if(v == fa) { if(cnt) low[u] = min(low[u], dfn[v]); cnt++; } else low[u] = min(low[u], dfn[v]); } } int tarjan() { int time = 0; for(int i=1; i<=n; i++) { if(!dfn[i]) { dfs(i, i); time++; } } return time; } int solve() { int ans = 0x3f3f3f3f; for(int u=1; u<=n; u++) { for(int i=head[u]; i!=-1; i=node[i].next) { int v = node[i].v; if(dfn[u] < low[v] && u != v) { ans = min(ans, node[i].w); } } } return ans; } int main() { while(scanf("%d%d",&n, &m), n||m) { init(); for(int i=1; i<=m; i++) { int u, v, w; scanf("%d%d%d", &u, &v, &w); addnode(u, v, w); addnode(v, u, w); } int time = tarjan(); if(time > 1) printf("0 "); else { int ans = solve(); if(ans == 0x3f3f3f3f) printf("-1 "); else if(ans == 0) printf("1 "); else printf("%d ", ans); } } return 0; }