Codeforces 527E. Data Center Drama 题解

题目大意:

  • 给定一个\(n\)个点\(m\)条边的无向图。
  • 你可以在这张无向图上加任意多条无向边。
  • 需要给所有的无向边定向,使得每一个的入度和出度都是偶数。
  • 边可以是自环,也可以是重边。

题目链接:527E. Data Center Drama


题解:考虑一个图能够这么定向的充要条件。就是一张图上,每一个点的度数是偶数并且边的总数是偶数。

这一道题我们发现一个很好的条件,就是可以连自环,并且自环不改变当前点度数的奇偶性。

那么直接把原图中度数为奇数的点两两连边,如果总边数变为奇数的话在连一个自环。

然后定向就直接一奇一偶一正一反就可以了。

代码:

#include <cstdio>
void read(int &a){
	a=0;
	char c=getchar();
	while(c<'0'||c>'9'){
		c=getchar();
	}
	while(c>='0'&&c<='9'){
		a=(a<<1)+(a<<3)+(c^48);
		c=getchar();
	}
}
const int Maxn=100000;
const int Maxm=300000;
int num;
bool vis[Maxm<<1|5];
int head[Maxn+5],arrive[Maxm<<1|5],nxt[Maxm<<1|5],tot;
int deg[Maxn+5];
void add_edge(int from,int to){
	arrive[++tot]=to;
	nxt[tot]=head[from];
	head[from]=tot;
}
int n,m;
int lis[Maxn+5],lis_len;
void dfs(int u){
	for(int &i=head[u];i;i=nxt[i]){
		if(vis[i]){
			continue;
		}
		int v=arrive[i];
		vis[i]=vis[((i-1)^1)+1]=1;
		dfs(v);
		num++;
		if(num&1){
			printf("%d %d\n",u,v);
		}
		else{
			printf("%d %d\n",v,u);
		}
	}
}
int main(){
	read(n),read(m);
	int u,v;
	for(int i=1;i<=m;i++){
		read(u),read(v);
		add_edge(u,v);
		add_edge(v,u);
		deg[u]++;
		deg[v]++;
	}
	for(int i=1;i<=n;i++){
		if(deg[i]&1){
			lis[++lis_len]=i;
		}
	}
	for(int i=1;i<=lis_len;i+=2){
		add_edge(lis[i],lis[i+1]);
		add_edge(lis[i+1],lis[i]);
		m++;
	}
	if(m&1){
		m++;
		add_edge(1,1);
		add_edge(1,1);
	}
	printf("%d\n",m);
	dfs(1);
	return 0;
}

猜你喜欢

转载自www.cnblogs.com/withhope/p/13392120.html
今日推荐