Hdu 4738 Caocao's Bridges (有重边无向图求桥)
来源:互联网 发布:现货白银看盘软件 编辑:程序博客网 时间:2024/06/09 13:49
2013杭州网络赛的第一题,坑点相当多,貌似这题导致15分钟没有队伍过题……
比赛时我负责这道题,WA9次才A。。。。。
从边数小于等于点数平方这点来看肯定有重边,需要处理。
图不连通,输出0.
如果取到的最小值是0的话,要输出1,表示要派一个人过去。
#include <cstdio>#include <cstring>#include <algorithm>using namespace std;#define min(a,b) ((a)<(b)?(a):(b))const int N=1005;const int M=N*N*2;struct Edge{int v,next,val;bool sign;}edge[M];int head[N],e;int dfn[N],low[N];int brg[M],cnt; //存储桥的权值及数量int top,dp; //dp存储搜索深度int n,m;void Add (int u,int v,int val){edge[e].v = v ;edge[e].val = val ;edge[e].next = head[u] ;edge[e].sign = false ;head[u] = e ++ ;}void Init (){memset(head,-1,sizeof(head));e=cnt=0;memset(dfn,0,sizeof(dfn));memset(low,0,sizeof(low));memset(brg,0,sizeof(brg));top=dp=0;}void tarjan (int now ,int fa){dfn[now] = low[now] = ++dp;bool first =false ;for (int i = head[now] ; ~i ; i = edge[i].next){int e = edge[i].v;if (edge[i].sign) continue;//无向图加双向边时必定相邻//处理后避免深搜的时候搜回去,经过重边再搜回来edge[i].sign = edge[i ^ 1].sign = true; if (!dfn[e]){tarjan(e,now);low[now] = min(low[now] ,low[e]);if (dfn[now] < low[e]) //是桥brg[cnt++] = edge[i].val ;}else low[now] = min(low[now] , dfn[e]);}}int main (){#ifdef ONLINE_JUDGE#elsefreopen("read.txt","r",stdin);#endif while (scanf("%d%d",&n,&m),n||m) {Init();int i,a,b,c;for (i=1;i<=m;i++){scanf("%d%d%d",&a,&b,&c);Add(a,b,c);Add(b,a,c);}int colornum=0; for (i=1;i<=n;i++) { top=dp=0; if (dfn[i]==0) tarjan (i,-1),colornum++; } if (colornum>1)//不连通printf("0\n");else if (cnt==0) //没有桥printf("-1\n");else{sort(brg,brg+cnt);if (brg[0]==0) //存在桥权值为0printf("1\n");elseprintf("%d\n",brg[0]);} } return 0;}
2014-7-31更新一种写法
#pragma comment(linker, "/STACK:1024000000,1024000000")#include <cstdio>#include <cstring>#include <algorithm>#define min(x,y) ((x)<(y)?(x):(y))#define max(x,y) ((x)>(y)?(x):(y))using namespace std;const int INF=0x3f3f3f3f;const int nPoint=1005;const int nEdges=1005*1005*2;int brg[nEdges];class BCC{public:struct Edge{int from, to,val, next;bool cut; //是否为桥}edge[nEdges];int e,id,n;int head[nPoint],dfn[nPoint], low[nPoint];int bridgetop;int colornum, top; //双连通分量数,栈顶int color[nPoint],Stack[nPoint];bool iscut[nPoint]; //该点是否为割点int bri_cut; //桥的数目void Add (int u, int v,int val){Edge E={u,v,val,head[u],false};edge[ e ] = E;head[u] = e++;}void Tarjan (int u, int pre){dfn[u]=low[u]=++id;Stack[++top]=u;int child=0, flag=1;for (int i=head[u]; ~i; i=edge[i].next){int v=edge[i].to;//if (v == pre) continue; //重边算一条的写法if (flag && v==pre){//重边有效的写法flag = 0; continue;}if (!dfn[v]){child++;Tarjan(v,u);low[u] = min(low[u], low[v]);if (low[v] >= dfn[u]){iscut[u] = true; //是割点if (low[v]>dfn[u])edge[i].cut = edge[i^1].cut = true; //是桥}}else low[u] = min(low[u], dfn[v]);}if (child == 1 && pre<0) //树根iscut[u] = false;if (low[u] == dfn[u]){colornum++;do{color[ Stack[top] ] = colornum;}while(Stack[top--] != u);}}void Init (int _n){n=_n;memset(head, -1, sizeof(head));memset(dfn, 0, sizeof(dfn));memset(iscut, 0, sizeof(iscut));memset(color, -1, sizeof(color));bridgetop =e=id= 0;top = colornum = 0;}bool Deal (){int i,flag=0;for (i=1; i<=n; i++) if (!dfn[i]){Tarjan(i, -1);flag++;}bri_cut = 0;for (i=0; i<e; i+=2)if (edge[i].cut){brg[bri_cut]=edge[i].val;bri_cut++;}if (flag==1) return true;return false;}}ob;int n,m;int main (){#ifdef ONLINE_JUDGE#elsefreopen("read.txt","r",stdin);#endif while (scanf("%d%d",&n,&m),n||m) {ob.Init(n);int i,a,b,c;for (i=1;i<=m;i++){scanf("%d%d%d",&a,&b,&c);ob.Add(a,b,c);ob.Add(b,a,c);}bool flag=ob.Deal();int cnt=ob.bri_cut;if (flag==false)//不连通printf("0\n");else if (cnt==0) //没有桥printf("-1\n");else{sort(brg,brg+cnt);if (brg[0]==0) //存在桥权值为0printf("1\n");elseprintf("%d\n",brg[0]);} } return 0;}
- Hdu 4738 Caocao's Bridges (有重边无向图求桥)
- HDU 4738 Caocao's Bridges(重边无向图求桥)
- HDU 4738 Caocao's Bridges(无向图求桥)
- HDU 4738 Caocao's Bridges(重边无向图求桥)
- HDU 4738 Caocao's Bridges(重边无向图求桥)
- HDU 4738 Caocao's Bridges 有重边的无向图求桥
- hdu 4738 Caocao's Bridges
- hdu 4738 Caocao's Bridges
- hdu 4738 Caocao's Bridges
- HDU:4738 Caocao's Bridges
- HDU 4738 Caocao's Bridges
- HDU 4738 Caocao's Bridges
- hdu 4738 - Caocao's Bridges
- hdu 4738 Caocao's Bridges
- HDU-4738Caocao's Bridges
- HDU 4738-Caocao's Bridges-无向图找桥 DAG Tarjan
- HDU 4738 Caocao's Bridges 无向图割边(水)
- hdu 4738 Caocao's Bridges -有重边的无向图找桥
- 关于堆和堆排序
- Two Minor Questions
- Struts2上传文件修改默认错误提示
- ffmpeg在windows下视频采集
- android中各种img文件的作用以及系统启动过程
- Hdu 4738 Caocao's Bridges (有重边无向图求桥)
- PHP使用mysqli扩展库实现增删改查(面向对象版)
- Windows Server 2012正式版RDS系列⒃
- UVA - 10306 e-Coins
- Android程序的安全系统--以root权限进行操作
- 顺序表的插入
- Windows Server 2012正式版RDS系列⒄
- 模拟U盘
- 找出一个字符串里面出现最多次数的字母以及次数