• 【模板】【hdu4738】Caocao's Bridges——tarjan求桥


    题目链接

    题目大意:

    曹操有N个岛,这些岛用M座桥连接起来,每座桥有士兵把守(也可能没有),

    诸葛亮把所有炸弹都带走了,只留下一枚给周瑜(真狠)。

    周瑜想让这N个岛不连通,但需要派出不小于守桥士兵数的人去炸桥,因为只有一枚炸弹,因此只够炸掉一座桥。

    分析:

    很明显的求代价最小的桥,当然这道题有几个特殊的地方:

    1.图本来就不联通,输出0;

    2.无解(不存在桥),输出-1;

    3.没人把守,但你还是得派一个人炸桥,输出1;

    4.一般情况,输出最小代价。

    剩下的就是模板了,不过需要注意的一点是,这道题可能有重边,因此只是不能走回这条边,而不一定不能走回这个点。

    代码:

     1 #include<cstdio>
     2 #include<cstring>
     3 #include<algorithm>
     4 #define mem(a,p) memset(a,p,sizeof(a))
     5 const int N=1e3+7,M=2e6+7;
     6 int read(){
     7     int ans=0,f=1;char c=getchar();
     8     while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
     9     while(c>='0'&&c<='9'){ans=ans*10+c-48;c=getchar();}
    10     return ans*f;
    11 }
    12 int n,tot,m,first[N],num,low[N],dfn[N],mni,ss;
    13 struct node{
    14     int ne,to,w;
    15     void operator = (const node&p){ne=p.ne;to=p.to;w=p.w;}
    16 }e[M];
    17 void ins(int u,int v,int c){e[++tot]=(node){first[u],v,c};first[u]=tot;}
    18 void init(){
    19     tot=0;num=0;mni=999999999;ss=0;
    20     mem(first,0);mem(dfn,0);mem(low,0);
    21 }
    22 void tarjan(int x,int fa){
    23     dfn[x]=low[x]=++num;
    24     for(int i=first[x];i;i=e[i].ne){
    25         int to=e[i].to;
    26         if(!dfn[to]){
    27             tarjan(to,x);
    28             if(low[to]<low[x])low[x]=low[to];
    29             if(low[to]>dfn[x]){
    30                 if(e[i].w<mni)mni=e[i].w;ss++;
    31             }
    32         }
    33         else if(to!=fa&&dfn[to]<low[x])low[x]=dfn[to];
    34     }
    35 }
    36 int main(){
    37     n=read();m=read();
    38     while(n||m){
    39         init();
    40         for(int i=1,a,b,c;i<=m;i++){
    41             a=read();b=read();c=read();
    42             ins(a,b,c);ins(b,a,c);
    43         }
    44         int flag=0;
    45         for(int i=1;i<=n;i++)
    46             if(!dfn[i]){
    47                 if(flag){flag=2;break;}
    48                 tarjan(i,0);
    49                 flag=1;
    50             }
    51         if(flag==2)printf("0
    ");
    52         else if(ss==0)printf("-1
    ");
    53         else if(mni==0)printf("1
    ");
    54         else printf("%d
    ",mni);
    55         n=read();m=read();
    56     }
    57     return 0;
    58 } 
    hdu4738
  • 相关阅读:
    重建二叉树
    替换空格
    四种类型转换符
    KVC和KVO简单介绍
    多线程之GCD的理解
    iOS常用代码
    iOS开发一些经常用到的第三方框架
    AS3 about Array.splice()
    sharedobject
    FlashBuilder的快捷键
  • 原文地址:https://www.cnblogs.com/JKAI/p/7808004.html
Copyright © 2020-2023  润新知