• hdoj 4738 Caocao's Bridges【双连通分量求桥】


    Caocao's Bridges

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


    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
    题意:曹操在长江上建造了n个岛屿,这些岛屿之间要用桥连接起来,每座桥上都派兵驻守,现在周瑜手中有一个炸弹,他要派人去炸掉其中一座桥,他派去的人数必须大于这条桥上驻守的人数,问他最少要派多少人去
    注意:1、如果图本来就不连通  不需要派人输出0
    2、如果桥上没有人把守,派去一个人即可
    3、如果炸掉桥还不能断开所有岛屿之间的的连接,输出-1
    #include<stdio.h>
    #include<string.h>
    #include<stack>
    #include<algorithm>
    #include<vector>
    #define MAX 1010
    #define MAXM 1000100
    #define INF 0x7ffffff
    using namespace std;
    int n,m,mark;//mark记录图是否联通 
    int head[MAX],ans;
    int low[MAX],dfn[MAX];
    int dfsclock,dcccnt;
    struct node
    {
    	int beg,end,val,next;
    	int cnt;//记录桥是否存在 
    }edge[MAXM];
    void init()
    {
    	ans=0;
    	memset(head,-1,sizeof(head));
    }
    void add(int u,int v,int w)
    {
    	edge[ans].beg=u;
    	edge[ans].end=v;
    	edge[ans].val=w;
    	edge[ans].cnt=0;//初始化为0表示没有桥 
    	edge[ans].next=head[u];
    	head[u]=ans++;
    }
    void getmap()
    {
    	int a,b,c;
    	while(m--)
    	{
    		scanf("%d%d%d",&a,&b,&c);
    		add(a,b,c);
    		add(b,a,c);
    	}
    }
    void tarjan(int u,int fa)
    {
    	int v;
    	low[u]=dfn[u]=++dfsclock;
    	int flag=1;
    	for(int i=head[u];i!=-1;i=edge[i].next)
    	{
    		v=edge[i].end;
    		if(flag&&v==fa)//判断重边 
            {
            	flag=0;
            	continue;
            }
            if(!dfn[v])
            {
            	tarjan(v,u);
            	low[u]=min(low[u],low[v]);
            	if(dfn[u]<low[v])//是桥
    			    edge[i].cnt=edge[i^1].cnt=1; //标记这条边是桥edge[i^1].cnt意思是这条边的反向边 
            }
            else 
                low[u]=min(low[u],dfn[v]);
    	}
    }
    void find()
    {
    	memset(dfn,0,sizeof(dfn));
    	memset(low,0,sizeof(low));
    	dfsclock=0;
    	tarjan(1,-1);
    	mark=1;
    	for(int i=1;i<=n;i++)//遍历所有点 
    	{
    		if(!dfn[i])//如果点没被搜索到证明这个图不连通 
    		{
    			mark=0;
    			return ;
    		} 
    	}
    }
    void solve()
    {
    	if(!mark)//图不连通  不需要派人 直接输出0 
    	    printf("0
    ");
    	else
    	{
    		int ant=INF;
    		for(int i=0;i<ans;i++)
    		{
    			if(edge[i].cnt)
    			    ant=min(ant,edge[i].val);//寻找人数最少把守的桥 
    		}
    		if(ant==INF)//如果不能阻断各岛屿之间的联系 
    		    ant=-1;
    		if(ant==0)//如果桥上的人数为0 派一个人 
    		    ant=1;
    		printf("%d
    ",ant);
    	}
    }
    int main()
    {
    	while(scanf("%d%d",&n,&m),n|m)
    	{
    		init();
    		getmap();
    		find();
    		solve();
    	}
    	return 0;
    }
    

      

  • 相关阅读:
    一个“会”用代码调色的Web前端开发,绝对是一个吃香的设计师
    如何区分html和html5,这可能是IE被黑最惨的一次,哈哈哈
    给程序员的 8 个提高开发效率的建议
    大厂面试经典问题:什么是继承 ?JavaScrpt中如何通过原型链实现继承 ?
    AD 差分线规则设置
    状态机阶段1 练习4
    状态机练习基于DAC8168C DAC电压输出
    Javascript ES6 / ES5在数组中查找并更改
    java: 程序包com.baomidou.mybatisplus.core.mapper不存在
    jar包上传maven私服
  • 原文地址:https://www.cnblogs.com/tonghao/p/4864348.html
Copyright © 2020-2023  润新知