Codeforces Beta Round #89 (Div. 2)E题,给一联通的无向图,求确定每边的方向,使得任意两点可达

来源:互联网 发布:ug8.0编程中的建模创 编辑:程序博客网 时间:2024/06/06 02:48
 
/*题意:给一无向图,现在要确定每边的方向,使得任意两点可达,一定存在。思想:用Tarjan算法求双连通分量,将深入的边与使low值变小的边存起来。其它还没确定的随便选个方向即可*/#include<stdio.h>#include<iostream>#include<algorithm>using namespace std;const int maxn=110000;const int maxm=2100000;struct edge{int u,v,next;bool flag;}e[maxm];int n,m,edgeNum,top,top1,cnt,tnum,first[maxn],low[maxn],DFN[maxn],q[maxn],q1[maxm];bool inq[maxn];void Addedge(int u,int v){e[edgeNum].u=u,e[edgeNum].v=v,e[edgeNum].flag=false,e[edgeNum].next=first[u],first[u]=edgeNum++;e[edgeNum].u=v,e[edgeNum].v=u,e[edgeNum].flag=false,e[edgeNum].next=first[v],first[v]=edgeNum++;}void DFS(int t,int p,int e1){DFN[t]=low[t]=++tnum;q[top++]=t;q1[top1++]=e1;if(e1!=-1) e[e1].flag=true;inq[t]=true;int j,k;for(k=first[t];k!=-1;k=e[k].next){j=e[k].v;if(j==p) continue;if(!DFN[j]){DFS(j,t,k);if(low[t]>low[j])low[t]=low[j];}else if(inq[j]&&low[t]>DFN[j]){q1[top1++]=k;//绕回去e[k].flag=true;low[t]=DFN[j];}}if(DFN[t]==low[t]){++cnt;do{inq[q[--top]]=false;}while(q[top]!=t);}}int main(){int i,u,v;while(scanf("%d%d",&n,&m)!=EOF){memset(first,-1,sizeof(first));edgeNum=0;for(i=0;i<m;i++){scanf("%d%d",&u,&v);Addedge(u,v);}memset(low,0,sizeof(low));memset(DFN,0,sizeof(DFN));memset(inq,false,sizeof(inq));top1=top=cnt=tnum=0;for(i=1;i<=n;i++)if(!DFN[i])DFS(i,-1,-1);if(cnt!=1){printf("0\n");continue;}//DFS1(1);for(i=0;i<edgeNum;i+=2)if(e[i].flag==false&&e[i+1].flag==false)q1[top1++]=i;//随便确定一个方向//printf("%d\n",top1);for(i=1;i<top1;i++)printf("%d %d\n",e[q1[i]].u,e[q1[i]].v);}return 0;}

原创粉丝点击