题意:给你一棵树,让你判断每一条的方向,使每一个节点出度为偶数。
显然,奇数个节点的图一定不符合,偶数个节点的图一定符合。
我们这样构造:
随便选一个根,
d
f
s
dfs
dfs出一棵生成树。其余边由深度大的点指向深度小的点。
回溯上来,对每一个点现有的出边数目进行讨论。
若为偶数,则由父节点指向本节点,否则由本节点指向父节点。
可以保证根节点也有偶数条出边。
C
o
d
e
:
Code:
Code:
#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;
}