hdu-4738.Caocao's Bridges(图中权值最小的桥)

Caocao's Bridges

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 10933    Accepted Submission(s): 3065


Problem Description
Caocao was defeated by Zhuge Liang and Zhou Yu in the battle of Chibi. But he wouldn't give up. Caocao's army still was not good at water battles, so he came up with another idea. He built many islands in the Changjiang river, and based on those islands, Caocao's army could easily attack Zhou Yu's troop. Caocao also built bridges connecting islands. If all islands were connected by bridges, Caocao's army could be deployed very conveniently among those islands. Zhou Yu couldn't stand with that, so he wanted to destroy some Caocao's bridges so one or more islands would be seperated from other islands. But Zhou Yu had only one bomb which was left by Zhuge Liang, so he could only destroy one bridge. Zhou Yu must send someone carrying the bomb to destroy the bridge. There might be guards on bridges. The soldier number of the bombing team couldn't be less than the guard number of a bridge, or the mission would fail. Please figure out as least how many soldiers Zhou Yu have to sent to complete the island seperating mission.
 
Input
There are no more than 12 test cases.

In each test case:

The first line contains two integers, N and M, meaning that there are N islands and M bridges. All the islands are numbered from 1 to N. ( 2 <= N <= 1000, 0 < M <= N 2 )

Next M lines describes M bridges. Each line contains three integers U,V and W, meaning that there is a bridge connecting island U and island V, and there are W guards on that bridge. ( U ≠ V and 0 <= W <= 10,000 )

The input ends with N = 0 and M = 0.
 
Output
For each test case, print the minimum soldier number Zhou Yu had to send to complete the mission. If Zhou Yu couldn't succeed any way, print -1 instead.
 
Sample Input
3 3 1 2 7 2 3 4 3 1 4 3 2 1 2 7 2 3 4 0 0
 
Sample Output
-1 4
 
Source
 
Recommend
liuyiding
 
 
下面的代码是使用并查集判环,实际上只需要在每次进行tarjan算法时给计数器加一,就知道有几个连通块了,在哪加我标出来了
  1 /*************************************************************************
  2     > File Name: hdu-4738.caocaos_bridges.cpp
  3     > Author: CruelKing
  4     > Mail: [email protected] 
  5     > Created Time: 2019年09月07日 星期六 21时41分41秒
  6     本题思路:无向图所有桥中权值的那条桥的权值.
  7     注意:有重边,如果桥上没敌人,需要有人抗tnt,因此需要输出1.
  8     如果初始图不连通则输出0.
  9  ************************************************************************/
 10 
 11 #include <cstdio>
 12 #include <cstring>
 13 #include <map>
 14 using namespace std;
 15 
 16 const int maxn = 1000 + 5, maxm = maxn * maxn + 5, inf = 0x3f3f3f3f;
 17 int n, m;
 18 int tot, head[maxn];
 19 
 20 int bridge, top, Index, min_bridge;
 21 int dfn[maxn], low[maxn], stack[maxn];
 22 bool instack[maxn];
 23 
 24 map<int, int> mp;
 25 
 26 struct Edge {
 27     int to, cost, next;
 28     bool cut;
 29 } edge[maxm << 1];
 30 
 31 int min(int x, int y) {
 32     return x > y ? y : x;
 33 }
 34 
 35 void init() {
 36     mp.clear();
 37     memset(head, -1, sizeof head);
 38     tot = 0;
 39 }
 40 
 41 void addedge(int u, int v ,int w) {
 42     edge[tot] = (Edge){v, w, head[u], false}; head[u] = tot ++;
 43     edge[tot] = (Edge){u, w, head[v], false}; head[v] = tot ++;
 44 }
 45 
 46 bool ishash(int u, int v) {
 47     return mp[u * maxn + v] ++ || mp[v * maxn + u] ++;
 48 }
 49 
 50 void tarjan(int u, int pre) {
 51     int v;
 52     stack[top ++] = u;
 53     instack[u] = true;
 54     dfn[u] = low[u] = ++ Index;
 55     int pre_cnt = 0;
 56     for(int i = head[u]; ~i; i = edge[i].next) {
 57         v = edge[i].to;
 58         if(v == pre && pre_cnt == 0) {
 59             pre_cnt ++;
 60             continue;
 61         }
 62         if(!dfn[v]) {
 63             tarjan(v, u);
 64             if(low[u] > low[v]) low[u] = low[v];
 65             if(low[v] > dfn[u]) {
 66                 edge[i].cut = true;
 67                 edge[i ^ 1].cut = true;
 68                 min_bridge = min(min_bridge, edge[i].cost);
 69                 bridge ++;
 70             }
 71         } else if(low[u] > dfn[v]) low[u] = dfn[v];
 72     }
 73     top --;
 74     instack[u] = false;
 75 }
 76 
 77 void solve() {
 78     memset(instack, false, sizeof instack);
 79     memset(dfn, 0, sizeof dfn);
 80     memset(low, 0, sizeof low);
 81     top = Index = bridge = 0;
 82     min_bridge = inf;
 83     for(int i = 1; i <= n; i ++) {
 84         if(!dfn[i]) {
 85             tarjan(i, i);//cnt ++;
 86         }
 87     }
 88     if(min_bridge == inf) min_bridge = -1;
 89     else if(min_bridge == 0) min_bridge = 1;//if cnt != 1 : min_bridge = 0;
 90     printf("%d\n", min_bridge);
 91 }
 92 
 93 int fa[maxn];
 94 
 95 int find(int x) {
 96     if(fa[x] != x) return fa[x] = find(fa[x]);
 97     else return x;
 98 }
 99 
100 void unionset(int u, int v) {
101     u = find(u);
102     v = find(v);
103     if(u != v) fa[u] = v;
104 }
105 
106 int main() {
107     int u, v, w;
108     while(~scanf("%d %d", &n, &m) && (n || m)) {
109         init();
110         for(int i = 1; i <= n; i ++) fa[i] = i;
111         for(int i = 0; i < m; i ++) {
112             scanf("%d %d %d", &u, &v, &w);
113 //            if(ishash(u, v)) continue;
114             addedge(u, v, w);
115             unionset(u, v);
116         }
117         bool flag = true;
118         for(int i = 1; i <= n; i ++)
119             if(find(i) != find(1)) {
120                 flag = false;
121                 break;
122             }
123         if(flag)
124             solve();
125         else printf("0\n");
126     }
127     return 0;
128 }

猜你喜欢

转载自www.cnblogs.com/bianjunting/p/11483825.html