AtCoder Grand Contest 035B-Even Degrees


题意:给你一棵树,让你判断每一条的方向,使每一个节点出度为偶数。
显然,奇数个节点的图一定不符合,偶数个节点的图一定符合。
我们这样构造:
随便选一个根,dfsdfs出一棵生成树。其余边由深度大的点指向深度小的点。
回溯上来,对每一个点现有的出边数目进行讨论。
若为偶数,则由父节点指向本节点,否则由本节点指向父节点。
可以保证根节点也有偶数条出边。
CodeCode:

#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;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章