标签:
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 3000 Accepted Submission(s):
953
#include<stdio.h>
#include<string.h>
#include<stack>
#include<algorithm>
#include<vector>
#define MAX 1010
#define MAXM 1000100
#define INF 0x7ffffff
using namespace std;
int n,m,mark;//mark记录图是否联通
int head[MAX],ans;
int low[MAX],dfn[MAX];
int dfsclock,dcccnt;
struct node
{
int beg,end,val,next;
int cnt;//记录桥是否存在
}edge[MAXM];
void init()
{
ans=0;
memset(head,-1,sizeof(head));
}
void add(int u,int v,int w)
{
edge[ans].beg=u;
edge[ans].end=v;
edge[ans].val=w;
edge[ans].cnt=0;//初始化为0表示没有桥
edge[ans].next=head[u];
head[u]=ans++;
}
void getmap()
{
int a,b,c;
while(m--)
{
scanf("%d%d%d",&a,&b,&c);
add(a,b,c);
add(b,a,c);
}
}
void tarjan(int u,int fa)
{
int v;
low[u]=dfn[u]=++dfsclock;
int flag=1;
for(int i=head[u];i!=-1;i=edge[i].next)
{
v=edge[i].end;
if(flag&&v==fa)//判断重边
{
flag=0;
continue;
}
if(!dfn[v])
{
tarjan(v,u);
low[u]=min(low[u],low[v]);
if(dfn[u]<low[v])//是桥
edge[i].cnt=edge[i^1].cnt=1; //标记这条边是桥edge[i^1].cnt意思是这条边的反向边
}
else
low[u]=min(low[u],dfn[v]);
}
}
void find()
{
memset(dfn,0,sizeof(dfn));
memset(low,0,sizeof(low));
dfsclock=0;
tarjan(1,-1);
mark=1;
for(int i=1;i<=n;i++)//遍历所有点
{
if(!dfn[i])//如果点没被搜索到证明这个图不连通
{
mark=0;
return ;
}
}
}
void solve()
{
if(!mark)//图不连通 不需要派人 直接输出0
printf("0\n");
else
{
int ant=INF;
for(int i=0;i<ans;i++)
{
if(edge[i].cnt)
ant=min(ant,edge[i].val);//寻找人数最少把守的桥
}
if(ant==INF)//如果不能阻断各岛屿之间的联系
ant=-1;
if(ant==0)//如果桥上的人数为0 派一个人
ant=1;
printf("%d\n",ant);
}
}
int main()
{
while(scanf("%d%d",&n,&m),n|m)
{
init();
getmap();
find();
solve();
}
return 0;
}
hdoj 4738 Caocao's Bridges【双连通分量求桥】
标签:
原文地址:http://www.cnblogs.com/tonghao/p/4864348.html