HDU4738(割边)

Caocao‘s Bridges

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

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 <= N2 )

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

2013 ACM/ICPC Asia Regional Hangzhou Online

题意:有n座岛和m条桥,每条桥上有w个兵守着,现在要派不少于守桥的士兵数的人去炸桥,只能炸一条桥,使得这n座岛不连通,求最少要派多少人去。

分析:只需要用Tarjan算法求出图中权值最小的那条桥就行了。但是这题有神坑。

第一坑:如果图不连通,不用派人去炸桥,直接输出0

第二坑:可能会有重边,即两座岛之间有多座桥(坑T_T)

第三坑:如果桥上没有士兵守着,那至少要派一个人去炸桥。

 1 //2016.9.16
 2 #include <iostream>
 3 #include <cstdio>
 4 #include <algorithm>
 5 #include <cstring>
 6 #define N 1005
 7
 8 using namespace std;
 9
10 const int inf = 0x3f3f3f3f;
11 int edge[N][N], vis[N], num[N], low[N], n, m, Index, ans, root;//vis表示连通的集合。
12
13 void tarjan(int cur, int fa)
14 {
15     Index++;
16     num[cur] = low[cur] = Index;
17     vis[cur] = 1;
18     for(int i = 1; i <= n; i++)
19     {
20         if(edge[cur][i]!=inf)
21         {
22             if(num[i] == 0)
23             {
24                 tarjan(i, cur);
25                 low[cur] = min(low[cur], low[i]);
26                 if(low[i]>num[cur])
27                       if(ans>edge[cur][i])
28                           ans = edge[cur][i];
29             }else if(i != fa)
30             {
31                 low[cur] = min(low[cur], num[i]);
32             }
33         }
34     }
35     return;
36 }
37
38 int main()
39 {
40     int u, v, w;
41     while(scanf("%d%d", &n, &m)!=EOF)
42     {
43         if(!n && !m)break;
44         memset(edge, inf, sizeof(edge));//图权值为inf表示断开
45         memset(num, 0, sizeof(num));
46         memset(low, 0, sizeof(low));
47         memset(vis, 0, sizeof(vis));
48         Index = 0, root = 1, ans = inf;
49         for(int i = 0; i < m; i++)
50         {
51             scanf("%d%d%d", &u, &v, &w);
52             if(edge[u][v] == inf)
53             {
54                 edge[u][v] = w;
55                 edge[v][u] = w;
56             }else//如果重边,必不为割边,但也不为断开,把权值设为inf一半
57             {
58                 edge[u][v] = inf/2;
59                 edge[v][u] = inf/2;
60             }
61         }
62         tarjan(1, root);
63         bool fg = true;//判断图是否连通
64         for(int i = 1; i <= n; i++)
65               if(!vis[i])
66             {
67                 printf("0\n");
68                 fg = false;
69                 break;
70             }
71         if(!fg)continue;
72         if(ans == inf || ans == inf/2)printf("-1\n");
73         else if(ans == 0)printf("1\n");//若无守兵,至少派一人去
74         else printf("%d\n", ans);
75     }
76
77     return 0;
78 }
时间: 2024-10-10 21:41:22

HDU4738(割边)的相关文章

[HDU4738]Caocao&#39;s Bridges(求割边最小权值)

http://acm.hdu.edu.cn/showproblem.php?pid=4738 #include<iostream> #include<cstdio> #include<cstring> #include<algorithm> using namespace std; const int maxn=1e3+4,maxm=1e6+4; int dfn[maxn],low[maxn],head[maxn]; int n,m,cnt=0,rt,ans

hdu-4738(tarjan割边)

题意:给你n个点,m条边,边有权值,问你最小的花费使图不连通: 解题思路:就是求边权最小的割边,但这道题有坑点: 1.有重边(桥的两个点有重边时,你去掉一条边并没什么d用): 2.当权值为0的时候,我们也需要放一个人(被这个坑死了0.0): #include<iostream> #include<algorithm> #include<cstdio> #include<cstring> #define maxn 1100 #define inf 0x3f3f

HDU 6214 最小割边

双倍经验题:HDU 6214,3987 求最小割的最小边. 方案一: 首先跑最大流,这个时候割上都满载了,于是将满载的边 cap = 1,其他 inf ,再跑最大流,这个时候限定这个网络的关键边就是那个最少边的那个割. 方案二: 奇技淫巧,将每条边 cap* A + 1,最大流 = flow / A ,最小割边 = fow % A: 原理:每条边容量扩大 到 cap * A + 1,那么最大流也一定扩大到 *A + 1,原图是多解,但是新图, 例如最少边的个是2条边,那么他就扩大到了 *A +

【学习整理】Tarjan:强连通分量+割点+割边

Tarjan求强连通分量 在一个有向图中,如果某两点间都有互相到达的路径,那么称中两个点强联通,如果任意两点都强联通,那么称这个图为强联通图:一个有向图的极大强联通子图称为强联通分量.   算法可以在 的时间内求出一个图的所有强联通分量. 表示进入结点 的时间 表示从 所能追溯到的栈中点的最早时间 如果某个点 已经在栈中则更新  否则对 进行回溯,并在回溯后更新  #include<iostream> #include<cstdlib> #include<cstdio>

hdu 3204(最小割--关键割边)

Ikki's Story I - Road Reconstruction Time Limit: 2000MS   Memory Limit: 131072K Total Submissions: 7491   Accepted: 2172 Description Ikki is the king of a small country – Phoenix, Phoenix is so small that there is only one city that is responsible fo

HDU 4738 Caocao&#39;s Bridges(割边)

乍一看一个模板题,仔细一看还是模板题,但是三个坑.1,不是连通图,放0个.2 守卫为0,放1个. 3注意重边. #include<iostream> #include<cstdio> #include<vector> #include<queue> #include<algorithm> #include<stack> #include<cstring> using namespace std; #define maxn

《啊哈算法》——割点、割边、二分图

这篇文章我们简单的介绍求解图的割点.割边和二分图相关的概念. 割点: 对于含n个点.m条边的连通无向图G,如果去掉顶点vi(并同时去掉与之相连的边),使得G不再连通,那么称vi是一个割点. 通过其定义,我们不难判断某个点是否是割点,但是现在我们面临的问题是,如何给出一个图G,编码让计算机求解割点呢? 首先我们考虑这样一个问题,判定某个点的指标是什么.我们通过人脑来判断其是否是割点,其实是利用非常模糊的视觉效应,即“通过去掉该点观察图是否连通”即可,而如果想要通过计算机来判断,就需要非常量化的判断

Burning Bridges 求tarjan求割边

Burning Bridges 给出含有n个顶点和m条边的连通无向图,求出所有割边的序号. 1 #include <cstdio> 2 #include <cstring> 3 #define clr(a) memset(a,0,sizeof(a)) 4 #define N 10005 5 #define M 100005 6 #define MIN(a,b) ((a)>(b)?(b):(a)) 7 typedef struct NodeStr //边结点 8 { 9 int

POJ3694(KB9-D 割边+LCA)

Network Time Limit: 5000MS   Memory Limit: 65536K Total Submissions: 10371   Accepted: 3853 Description A network administrator manages a large network. The network consists of N computers and M links between pairs of computers. Any pair of computers