hdu 4738 无向图求桥
1 /* 2 题意:给出n个岛屿,m座桥连接,每座桥由w个人守住,给出一个炸弹可以炸毁一座桥,而炸每座桥之前 3 要先将桥上的敌人消灭,最少需要w人,问最少需要多少人才能炸毁其中的一座桥 4 5 题解:无向图求桥 6 注意:有重边,当桥上人数为0时,最少应该需要1人(需要有一个人带着炸弹过去) 7 */ 8 #include <cstdio> 9 #include <cstring> 10 #include <algorithm> 11 12 using namespace std; 13 14 #define MAXN 1005 15 #define MAXM 1000005 16 17 const int INF = 100000; 18 19 struct node { 20 int v, w, pre, id; //id:边的编号(处理重边情况) 21 } edge[MAXM]; 22 int pos[MAXN], nEdge; //图的存储:链式前向星(池子法) 23 24 struct Bridge { 25 int u, v, w; 26 } bridge[MAXM]; //用来记录桥 27 int tot; //桥的个数 28 29 int fa[MAXN], cc; //fa:各个点所属的缩点(连通块),cc连通块的个数 30 int dfn[MAXN], low[MAXN], time; //时间戳 31 int stack[MAXN], top; //用于维护连通块的 32 int n, m; //点的个数和边的条数 33 34 void connect(int u, int v, int w, int id) { 35 nEdge++; 36 edge[nEdge].pre = pos[u]; 37 edge[nEdge].v = v; 38 edge[nEdge].w = w; 39 edge[nEdge].id = id; 40 pos[u] = nEdge; 41 } 42 43 void tarjan(int cur, int from) { 44 low[cur] = dfn[cur] = time++; 45 stack[++top] = cur; 46 for (int p=pos[cur]; p; p=edge[p].pre) { 47 int v = edge[p].v; 48 if (edge[p].id == from) continue; 49 if (!dfn[v]) { 50 tarjan(v, edge[p].id); 51 if (low[v] < low[cur]) low[cur] = low[v]; 52 if (low[v] > dfn[cur]) { 53 bridge[tot].u = cur; 54 bridge[tot].w = edge[p].w; 55 bridge[tot++].v = v; 56 cc++; 57 do { 58 fa[stack[top]] = cc; 59 } while (stack[top--] != v); 60 } 61 } else if (low[cur] > dfn[v]) low[cur] = dfn[v]; 62 } 63 } 64 int main(void) 65 { 66 while(~scanf("%d%d", &n, &m), n || m) 67 { 68 memset(pos, 0, sizeof(pos)); 69 nEdge = 0; 70 int u, v, w; 71 for (int i=0; i<m; i++) { 72 scanf("%d%d%d", &u, &v, &w); 73 connect(u, v, w, i); 74 connect(v, u, w, i); 75 } 76 77 memset(dfn, 0, sizeof(dfn)); 78 memset(fa, -1, sizeof(fa)); 79 80 cc = tot = 0; 81 if (!dfn[1]) { 82 top = time = 1; 83 tarjan(1, -1); 84 ++cc; 85 int j; 86 for (j=1; j<=n; j++) //特殊处理顶点的连通块 87 { 88 if (dfn[j]) 89 { 90 if (fa[j] == -1) 91 fa[j] = cc; 92 } 93 else 94 break; 95 } 96 if (j <= n) 97 printf("0\n"); 98 else 99 { 100 int minw = INF; 101 if (tot > 0) 102 { 103 for(int i=0; i<tot; i++) 104 minw = min(bridge[i].w,minw); 105 if (minw == 0) 106 minw = 1; 107 printf("%d\n",minw); 108 } 109 else 110 printf("-1\n"); 111 } 112 } 113 } 114 return 0; 115 }