zoukankan      html  css  js  c++  java
  • hdu 4738 Caocao's Bridges 求无向图的桥【Tarjan】

    <题目链接>

    题目大意:

      曹操在长江上建立了一些点,点之间有一些边连着。如果这些点构成的无向图变成了连通图,那么曹操就无敌了。周瑜为了防止曹操变得无敌,就打算去摧毁连接曹操的点的桥。但是诸葛亮把所有炸弹都带走了,只留下一枚给周瑜。所以周瑜只能炸一条桥。

      题目给出n,m。表示有n个点,m条桥。

      接下来的m行每行给出a,b,c,表示a点和b点之间有一条桥,而且曹操派了c个人去守卫这条桥。

      现在问周瑜最少派多少人去炸桥。

      如果无法使曹操的点成为多个连通图,则输出-1.

    解题思路:

      就是用Tarjan找出图中所有的桥,并且不断更新所有桥上防守人数最少的值。

    需要注意几点:

      1.首先先判断整张图是否为连通图,如果不为连通图,则无需派人去炸桥;

      2.如果原图不存在桥,即,只炸毁一条边不能够破坏原图的连通性,就直接输出-1;

      3.如果防守人数最少的那个桥上的防守人数为0,也需要派人去炸桥,因为那座桥不会自动毁坏。

     1 #include<iostream>
     2 #include<algorithm>
     3 #include<cstdio>
     4 #include<cstring>
     5 #include<cstdlib>
     6 using namespace std;
     7 const int maxn = 1007;
     8 const int INF = 0x3f3f3f3f;
     9 struct node{
    10     int to,cost,next;
    11 };
    12 node edge[maxn*maxn];
    13 int head[maxn],n,m,num,ans,sum,dfn[maxn],child,low[maxn];
    14 void addedge(int u,int v,int c){    //双向存图
    15     edge[num].to=v;edge[num].cost=c;edge[num].next=head[u];
    16     head[u]=num++;
    17     edge[num].to=u;edge[num].cost=c;edge[num].next=head[v];
    18     head[v]=num++;
    19 }
    20 void tarjan(int u,int fa){
    21     child++;     //child记录连通到的点的数量
    22     low[u]=dfn[u]=sum++;
    23     for(int i=head[u];i!=-1;i=edge[i].next){
    24         int v=edge[i].to;
    25         if(i==(fa^1)) continue;    //标记反向边 
    26         if(!dfn[v]){
    27             tarjan(v,i);
    28             low[u]=min(low[u],low[v]);
    29             if(dfn[u]<low[v]){    //桥的判定方法  因为low[v]<dfn[u],说明v和u不属于同一联通块,并且v不能通过u-v之间的边到达比low[v]小的点,说明这条边为桥
    30                 ans=min(ans,edge[i].cost);    //更新权值最小的桥
    31             }
    32         }
    33         else low[u]=min(low[u],dfn[v]);
    34     }
    35 }
    36 
    37 int main(){
    38     int a,b,c;
    39     while(~scanf("%d%d",&n,&m),n||m){
    40         memset(head,-1,sizeof(head));
    41         memset(dfn,0,sizeof(dfn));
    42         memset(low,0,sizeof(low));
    43         ans=INF;child=0;sum=1;
    44         for(int i=1;i<=m;i++){
    45             scanf("%d%d%d",&a,&b,&c);
    46             addedge(a,b,c);      
    47         }
    48         tarjan(1,-1);
    49         if(child<n) printf("0
    ");    //如果原图本来就不是连通图,就直接输出0即可
    50         else if(ans==INF)printf("-1
    "); //如果没有桥,即,只派出一个人不能将原图的连通性破坏,就直接输出-1
    51         else if(ans==0) printf("1
    ");   //如果桥上无人防守,也需要派人去把那座桥炸毁   
    52         else printf("%d
    ",ans);
    53     }
    54     return 0;
    55 }

    2018-08-17

  • 相关阅读:
    跨域访问(nginx)
    mybatis中<set>标签和<trim prefix="set" suffixOverrides=",">
    如何在Oracle中复制表结构和表数据
    Oracle删除重复数据
    Oracle中删除表
    Oracle中on和where的区别
    Java实体类中的类型对应mybatis的jdbcType
    Java 枚举(enum) 常见用法
    关于JS 事件冒泡和onclick,click,on()事件触发顺序
    浅析 SpringMVC 的@PathVariable 和 @RequestParam 和 @RequestBody注解
  • 原文地址:https://www.cnblogs.com/00isok/p/9490907.html
Copyright © 2011-2022 走看看