HDU4738 Caocao‘s Bridges (Tarjan判重边桥)

题目链接2013 ACM/ICPC Asia Regional Hangzhou Online
在这里插入图片描述
题意挺有意思的。曹操的军队在若干个岛屿之间修了桥,使得U–V联通,周瑜现在要去炸一座桥,使得其余岛屿不再能任意相互到达。爆破小队的人数必须大于等于该桥的守卫人数才能完成任务。现在请输出周瑜最少要派多少人或者输出-1 说明无法实现炸桥以后,破坏连通性。

问题分析:
显然这是一道求割边(桥)的题。Tarjan处理,注意重边,注意如果一开始就不连通,是不需要派人的,数量为0.但是如果存在桥且边权为0,就要派1人。其余情况自然洒洒水啦。

#include<bits/stdc++.h>
#include<algorithm>
#include<cstring>
#include<cstdio>
#define Re int
using namespace std;
const int N=3e4+3,M=1e6+200;
int n,m,x,y,ans,w,sc;
inline void in(Re &x){
    int f=0;x=0;char c=getchar();
    while(c<'0'||c>'9')f|=c=='-',c=getchar();
    while(c>='0'&&c<='9')x=(x<<1)+(x<<3)+(c^48),c=getchar();
    x=f?-x:x;
}
struct Tarjan{
    int o,dfn_o,dfn[N],low[N],head[N],bridge[M<<1];
    struct QAQ{int to,next,w;}a[M<<1];
    inline void add(Re x,Re y,Re w){a[++o].to=y,a[o].w=w,a[o].next=head[x],head[x]=o;}
    inline void CL(){
        memset(bridge,0,sizeof(bridge));
        memset(head,0,sizeof(head));
        memset(low,0,sizeof(low));
        memset(dfn,0,sizeof(dfn));
        dfn_o=0,o=1;
        ans=99999999;
        sc=0;
    }
    inline void tarjan(Re x,Re p){
        dfn[x]=low[x]=++dfn_o;
        for(Re i=head[x],to;i;i=a[i].next)
            if(!dfn[to=a[i].to]){
                tarjan(to,i);
                low[x]=min(low[x],low[to]);
                if(low[to]>dfn[x])bridge[i]=bridge[i^1]=1,ans=min(ans,a[i].w);
            }
            else if(i!=(p^1))low[x]=min(low[x],dfn[to]);
    }
    inline void get_bridg(){for(Re i=1;i<=n;++i)if(!dfn[i])tarjan(i,-1),sc++;}
}T1;
int main(){
    while(scanf("%d%d",&n,&m)!=EOF){
            if(n<=0&&m<=0)break;
        T1.CL();
       // ans=1000000000;
        while(m--)in(x),in(y),in(w),T1.add(x,y,w),T1.add(y,x,w);
        T1.get_bridg();
       if(sc>=2){
        printf("0\n");
        continue;
       }
      if(ans<99999999){
            if(ans==0)ans++;
        printf("%d\n",ans);
      }
      else printf("-1\n");
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值