0
点赞
收藏
分享

微信扫一扫

HDOJ 4738 - Caocao's Bridges 用tarjan找无向图的桥..注意trick

成义随笔 2022-08-12 阅读 20


              题意:

                       赤壁之战,曹操把所有的船都用桥连起来了...如果船都是联通的..则曹操是必胜的..而现在周瑜可以用一个炸弹炸掉一个桥..若能让曹操的所有船不联通..则可以逆转局势获得胜利..但是要炸某个桥..就必须派出一些士兵去执行..现在告诉有哪些桥.在哪两点间.并且炸掉这个桥所需要的士兵数量..问周瑜能否逆转局势,并且所需要的兵力最少是多少..

              题解:

                       总的来说..用tarjan求出桥..然后找到所需士兵最小的桥就是答案了..但要注意两个情况:

                      1、图是不联通的..那么不需要炸桥了..代价为0

                      2、要炸毁桥..必须派出兵力..也就是说当最小的桥所需兵力为0时..答案也是1..因为根据提议.需要一个人来背炸药的...


Program:

#include<iostream>
#include<stack>
#include<queue>
#include<stdio.h>
#include<algorithm>
#include<string.h>
#include<cmath>
#define ll long long
#define oo 1000000007
#define eps 1e-5
#define MAXN 3005
#define MAXM 3000005
using namespace std;
struct node
{
int x,y,l,id,next;
}edge[MAXM];
int Lnum,_next[MAXN],dfn[MAXN],low[MAXN],DfsIndex,father[MAXN];
bool brige[MAXM];
void addedge(int x,int y,int l,int id)
{
edge[++Lnum].next=_next[x],_next[x]=Lnum;
edge[Lnum].x=x,edge[Lnum].y=y,edge[Lnum].l=l,edge[Lnum].id=id;
swap(x,y);
edge[++Lnum].next=_next[x],_next[x]=Lnum;
edge[Lnum].x=x,edge[Lnum].y=y,edge[Lnum].l=l,edge[Lnum].id=id;
}
void tarjan(int x,int id)
{
int y,k;
dfn[x]=low[x]=++DfsIndex;
for (k=_next[x];k;k=edge[k].next)
{
if (edge[k].id==id) continue;
y=edge[k].y;
if (!dfn[y])
{
tarjan(y,edge[k].id);
low[x]=min(low[x],low[y]);
if (dfn[x]<low[y]) brige[k]=true;
}else
low[x]=min(low[x],dfn[y]);
}
return;
}
int getfather(int x)
{
if (father[x]==x) return x;
return father[x]=getfather(father[x]);
}
int main()
{
int n,m,x,y,i,l,ans;
while (~scanf("%d%d",&n,&m) && n)
{
Lnum=0,memset(_next,0,sizeof(_next));
for (i=1;i<=n;i++) father[i]=i;
for (i=1;i<=m;i++)
{
scanf("%d%d%d",&x,&y,&l);
if (!l) l=1;
addedge(x,y,l,i);
father[getfather(x)]=getfather(y);
}
for (i=2;i<=n;i++)
if (getfather(i)!=getfather(1)) break;
if (i<=n)
{
printf("0\n");
continue;
}
memset(brige,false,sizeof(brige));
memset(dfn,false,sizeof(dfn)),DfsIndex=0;
ans=oo;
tarjan(1,0);
for (i=1;i<=Lnum;i++)
if (brige[i]) ans=min(ans,edge[i].l);
if (ans==oo) printf("-1\n");
else printf("%d\n",ans);
}
return 0;
}




举报

相关推荐

0 条评论