标签:
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