1. 程式人生 > >HDU 4738 Caocao's Bridges (橋的權最小)

HDU 4738 Caocao's Bridges (橋的權最小)

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

題意:曹操在赤壁戰役中被諸葛亮和周瑜打敗。但他不會放棄。曹操的軍隊還不擅長水戰,所以他又想出了一個主意。曹操在長江上修建了許多島嶼,在這些島嶼的基礎上,曹操的軍隊可以輕易地攻擊周瑜的軍隊。曹操還修建了連線島嶼的橋樑。如果所有的島嶼都用橋樑連線起來,曹操的軍隊就可以很方便地部署在這些島嶼之間。周瑜無法忍受,他想摧毀曹操的一些橋樑,這樣一個或多個島嶼就會和其他島嶼分開。但是周瑜只有一顆炸彈,那是諸葛亮留下的,所以他只能摧毀一座橋。周瑜必須派人攜帶炸彈摧毀大橋。橋上可能有守衛。轟炸隊的士兵人數不能少於一座橋的警衛人數,否則任務就會失敗。請至少算出周瑜到底要派多少士兵去完成島上的分離任務。

坑點:有重邊。

           如果是不是連通圖輸出0.

           如果守橋人數是0,至少要排一人。

思路:求橋的模板題。坑點多而已。

#include<algorithm>
#include<string.h>
#include<stdio.h>
#define M 1010
using namespace std;
struct path
{
    int to,nextt,v;
} A[M*M*2];
int head[M],DFN[M],LOW[M];
int n,m,tot,carry,indox,ans;
void init()
{
    ans=0x3f3f3f3f;
    carry=tot=indox=0;
    memset(head,-1,sizeof(head));
    memset(DFN,-1,sizeof(DFN));
    memset(LOW,-1,sizeof(LOW));
}
void add(int x,int y,int v)
{
    A[tot].to=y;
    A[tot].v=v;
    A[tot].nextt=head[x];
    head[x]=tot++;
}
void tarjan(int u,int p)
{
    int tem;
    DFN[u]=LOW[u]=++indox;
    for(int i=head[u]; i!=-1; i=A[i].nextt)
    {
        tem=A[i].to;
        if(i==p) continue;
        if(DFN[tem]==-1)
        {
            tarjan(tem,i^1);
            LOW[u]=min(LOW[u],LOW[tem]);
            if(LOW[tem]>DFN[u])
            {
                ans=min(ans,A[i].v);
            }
        }
        else
        {
            LOW[u]=min(LOW[u],DFN[tem]);
        }
    }
}
int main()
{
    int x,y,v,flag;
    while(~scanf("%d%d",&n,&m),n||m)
    {
        init();
        flag=0;
        for(int i=1; i<=m; i++)
        {
            scanf("%d%d%d",&x,&y,&v);
            add(x,y,v);
            add(y,x,v);
        }
        for(int i=1; i<=n; i++)
        {
            if(DFN[i]==-1)
            {
                tarjan(i,-1);
                flag++;
            }

        }
        if(flag>1)
            printf("0\n");
        else if(ans>1000000)
            printf("-1\n");
        else if(ans==0)
            printf("1\n");
        else
            printf("%d\n",ans);
    }
}