zoukankan      html  css  js  c++  java
  • 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): 4254    Accepted Submission(s): 1337

    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

    Recommend

    liuyiding

    题意:

           现在有个(可重边)无向图,无向图的每条边上都有一定数目的守卫,你现在想派人去炸掉这个图的一条边,是的该图不连通。但是你只能炸1条边且如果该边守卫为x人,那么你至少要派x个人过去。所以现在问你最少需要派多少人出发?

    分析:

          本题的本质还是无向图求桥,且求得是守卫数目最少的那个桥。但是本题有3个点要注意:

    1.所给的图可能不连通,且不连通的时候不需要炸,输出0.

    2.当所要去炸的桥上的守卫数=0时,我们需要派的人数是1不是0.

    3.任意两个节点u与v之间可能存在多条边。

    前两点都挺好解决的,无非是加判断语句

    对于重边的问题,是这样处理的:

    放弃一般的模版直接比较父节点的做法,去比较边与递归上一层的“父边”是否是同时添加进去的,即可能可在这个点返回其父节点(有重边时)

    具体看代码:

      1 #include<cstdio>
      2 #include<cstring>
      3 #include<algorithm>
      4 using namespace std;
      5 const int maxn=1000+10;
      6 const int maxm=2*1000*1000+100;
      7 int n,m;
      8 int tot;
      9 int head[maxn];
     10 struct Edge
     11 {
     12     int to,next,w;
     13 }edges[maxm];
     14 void add_edge(int u,int v,int w)
     15 {
     16     edges[tot]=(Edge){v,head[u],w};
     17     head[u]=tot++;
     18     edges[tot]=(Edge){u,head[v],w};
     19     head[v]=tot++;
     20 }
     21 
     22 int pre[maxn],low[maxn];
     23 int dfs_clock,point_num;
     24 int ans;
     25 void tarjan(int u,int E)
     26 {
     27     low[u]=pre[u]=++dfs_clock;
     28     for(int e=head[u];e!=-1;e=edges[e].next)
     29     {
     30         int v=edges[e].to;
     31         if(e==(E^1)) continue;
     32         if(!pre[v])
     33         {
     34             tarjan(v,e);
     35             low[u]=min(low[u],low[v]);
     36             if(low[v]>pre[u])
     37                 ans=min(ans,edges[e].w);
     38         }
     39         else low[u]=min(low[u],pre[v]);
     40     }
     41     point_num++;
     42 }
     43 int main()
     44 {
     45     while(scanf("%d%d",&n,&m)==2&&n)
     46     {
     47         ans=1000000;
     48         dfs_clock=point_num=tot=0;
     49         memset(pre,0,sizeof(pre));
     50         memset(head,-1,sizeof(head));
     51         for(int i=0;i<m;i++)
     52         {
     53             int u,v,w;
     54             scanf("%d%d%d",&u,&v,&w);
     55             add_edge(u,v,w);
     56         }
     57         tarjan(1,-1);
     58         if(point_num<n) printf("0
    ");          //图不连通,不用炸
     59         else if(ans==1000000) printf("-1
    ");   //图中无桥
     60         else if(ans==0) printf("%d
    ",1);       //桥上兵为0
     61         else printf("%d
    ",ans);
     62     }
     63     return 0;
     64 }
    View Code
  • 相关阅读:
    ms sql 生成日历储存过程
    基于开源的GOCW和Directshow.net,实现摄像头预览、采集、录像等操作
    xshell链接远程服务器centos7显示-bash-4.2#
    docker服务日志查看方法
    信息技术应用技巧:没有音箱怎么办?手机当音箱
    信息技术应用技巧:台式机没有网线怎么办?
    C# 查找PDF页面指定区域中的文本并替换和高亮
    Java 将Excel工作簿按工作表拆分为多个文档
    Java 查找并替换PDF中的指定文本
    【SqlServer】导入MaxMind中的IP数据(.csv)文件到SQL Server数据库(转)
  • 原文地址:https://www.cnblogs.com/liuzhanshan/p/6727247.html
Copyright © 2011-2022 走看看