題意:給你一棵樹,讓你判斷每一條的方向,使每一個節點出度爲偶數。
顯然,奇數個節點的圖一定不符合,偶數個節點的圖一定符合。
我們這樣構造:
隨便選一個根,出一棵生成樹。其餘邊由深度大的點指向深度小的點。
回溯上來,對每一個點現有的出邊數目進行討論。
若爲偶數,則由父節點指向本節點,否則由本節點指向父節點。
可以保證根節點也有偶數條出邊。
#include<bits/stdc++.h>
using namespace std;
const int N=2e5+5;
int n,m,tot=0,b[N],deep[N],sum[N],blog[N],head[N];
struct node
{
int vet,nxt,flag;
}edge[N];
void add(int u,int v)
{
edge[++tot].vet=v;
edge[tot].nxt=head[u];
head[u]=tot;
}
void dfs(int u,int fa)
{
b[u]=1;
deep[u]=deep[fa]+1;
for(int i=head[u];i;i=edge[i].nxt)
{
int v=edge[i].vet;
if(v==fa)continue;
if(!b[v])
{
dfs(v,u);
if(blog[v])
{
edge[i].flag=1;
sum[u]++;
}
}else
if(deep[v]<deep[u])
{
edge[i].flag=1;
sum[u]++;
}
}
if(sum[u]%2==1)
{
for(int i=head[u];i;i=edge[i].nxt)
if(edge[i].vet==fa)
{
edge[i].flag=1;
sum[u]++;
break;
}
}else blog[u]=1;
}
int main()
{
scanf("%d%d",&n,&m);
if(m%2==1)
{
puts("-1");
return 0;
}
for(int i=1;i<=m;i++)
{
int u,v;
scanf("%d%d",&u,&v);
add(u,v);add(v,u);
}
memset(b,0,sizeof(b));
memset(deep,0,sizeof(deep));
memset(sum,0,sizeof(sum));
memset(blog,0,sizeof(blog));
dfs(1,0);
for(int u=1;u<=n;u++)
for(int i=head[u];i;i=edge[i].nxt)
if(edge[i].flag)
printf("%d %d\n",u,edge[i].vet);
return 0;
}