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