hdu4738——橋(割邊)

題目鏈接:http://acm.hdu.edu.cn/showproblem.php?pid=4738

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

題目翻譯

曹操在赤壁戰役中被諸葛亮和周瑜擊敗。但他不會放棄的曹操的軍隊還不擅長水戰,所以他想出了另一個主意。他在長江上建了許多島嶼,以這些島嶼爲基礎,曹操的軍隊很容易攻擊周瑜的軍隊。曹操還修建了連接島嶼的橋樑。如果所有島嶼都通過橋樑相連,曹操的軍隊就可以在這些島嶼之間部署得非常方便。周瑜受不了,所以他想摧毀一些曹操的橋樑,這樣一個或多個島嶼就會與其他島嶼分開。但周瑜只有一顆原子彈是諸葛亮留下的,所以他只能摧毀一座橋。周宇必須派人攜帶炸彈去摧毀這座橋。橋上可能有警衛轟炸隊的士兵人數不能少於一座橋的警衛人數,否則任務就會失敗。請算出周瑜要派多少戰士來完成海島分島任務。‎

‎輸入‎

‎測試用例不超過 12 個。在每個測試用例中:‎

‎第一行包含兩個整數,N 和 M,這意味着有 N 個孤島和 M 橋。 ‎
‎ ‎
‎所有島嶼的編號從 1 到 N ( 2 <= N <= 1000, 0 < M <= N ‎‎2‎‎ )‎

‎下一個 M 線描述 M 網橋。每行包含三個整數 U、V 和 W,這意味着有一個連接您島和島嶼 V 的橋,並且橋上有 W 防護裝置。(U = V 和 0 <= W <= 10,000)‎
‎輸入以 N = 0 和 M = 0‎
‎結束。‎

‎輸出‎

‎對於每個測試用例,打印周瑜爲完成任務而必須發送的最低士兵編號。如果周瑜不能成功,請改爲打印-1。

 

其實就是讓你求割邊的個數,但是這個題有幾個trick,

1、就是兩點之間可能有重邊

2、初始狀態的圖已經不是連通的了

3、某個橋就算沒人守也至少派要一個人去炸橋

#include <bits/stdc++.h>
using namespace std;
const int maxn=1e3+5;
const int INF=0x3f3f3f3f;
int head[maxn],low[maxn],dfn[maxn],cut[maxn];
int n,m,total,cut_cnt,dfs_clock,union_num;
struct Edge{
	int to,nxt;
	int w;
}edge[maxn*maxn*2];
void init(){
	memset(head,-1,sizeof(head));
	memset(low,0,sizeof(low));
	memset(dfn,0,sizeof(dfn));
	dfs_clock=cut_cnt=total=0;
	union_num=1;
}
void addedge(int from,int to,int w){
	edge[total].to=to;
	edge[total].w=w;
	edge[total].nxt=head[from];
	head[from]=total++;
}
void dfs(int cur,int father){
	low[cur]=dfn[cur]=++dfs_clock;
	int pre_num=0;
	for(int i=head[cur];i!=-1;i=edge[i].nxt){
		int v=edge[i].to;
		if(v==father&&pre_num==0){
			pre_num++; 
			continue;
		}
		if(!dfn[v]){
			union_num++;
			dfs(v,cur);
			low[cur]=min(low[cur],low[v]);
			if(low[v]>dfn[cur])
				cut[cut_cnt++]=edge[i].w; 
		}
		else if(dfn[v]<dfn[cur]){
			low[cur]=min(low[cur],dfn[v]);
		}
	}
}
int main(int argc, char** argv) {
	while(~scanf("%d%d",&n,&m)&&n&&m){
		init();
		while(m--){
			int u,v,w;
			scanf("%d%d%d",&u,&v,&w);
			addedge(u,v,w);
			addedge(v,u,w);
		}
		dfs(1,1);
		if(union_num<n) printf("0\n");
		else{
			int mincost=INF;
			for(int i = 0;i<cut_cnt;++i)
				mincost=min(mincost,cut[i]);
			if(mincost==INF) mincost=-1;
			printf("%d\n",mincost==0?1:mincost);
		}
	}
	return 0;
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章