题意:有N个点,M条无向边,决定每条边的方向,使得图中任何一个点都能到达其他点。
起先想着如何去决定每条边的方向,无果,最后发现其实只要dfs一次就可以,挺有意思的一道题。
#include <iostream>
#include <cstdio>
#include <cstring>
#include <string>
#include <vector>
#include <algorithm>
#include <queue>
#include <set>
#include <map>
using namespace std;
typedef long long LL;
typedef pair<int,int> PII;
const int N=1e5+5;
struct Edge
{
int v,pre;
Edge(){}
Edge(int v,int pre) :
v(v),pre(pre) {}
}edge[N*7];
int head[N],nEdge;
int dfn[N],low[N],nId;
int n,m;
vector<PII> ans;
void Init()
{
nEdge=0; nId=0;
memset(head,-1,sizeof(head));
memset(dfn,0,sizeof(dfn));
memset(low,0,sizeof(low));
}
void addEdge(int u,int v)
{
edge[nEdge]=Edge(v,head[u]);
head[u]=nEdge++;
}
bool tarjan(int u,int pre)
{
dfn[u]=low[u]=++nId;
bool flag=0;
for(int i=head[u];i!=-1;i=edge[i].pre)
{
int v=edge[i].v;
if(v==pre&&flag==0)
{
flag=1; continue;
}
if(dfn[v])
{
if(dfn[v]>dfn[u]) continue;
low[u]=min(low[u],dfn[v]);
ans.push_back(make_pair(u,v));
}
else
{
if(tarjan(v,u)==0) return false;
low[u]=min(low[u],low[v]);
if(low[v]>dfn[u]) return false;
ans.push_back(make_pair(u,v));
}
}
return true;
}
int main()
{
//freopen("in.txt","r",stdin);
while(scanf("%d%d",&n,&m)!=EOF)
{
Init();
for(int i=0;i<m;i++)
{
int a,b; scanf("%d%d",&a,&b);
addEdge(a,b);
addEdge(b,a);
}
if(tarjan(1,-1)==0) puts("0");
else
{
int len=(int)ans.size();
for(int i=0;i<len;i++)
{
printf("%d %d\n",ans[i].first,ans[i].second);
}
}
}
return 0;
}