/* 题意:给一无向图,现在要确定每边的方向,使得任意两点可达,一定存在。 思想:用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; }