Codeforces 547D. Mike and Fish 题解

题目链接:D. Mike and Fish

题目大意:洛谷


题解:考虑将点作为边,给定的每一个点将它的横坐标和纵坐标之间连一条边。那么问题就转化为了要求每一个点的入度和出度之差不超过 1 。

考虑到度数为奇数的点有一些麻烦,所以我们可以将度数为奇数的点连接到一个新建的虚点上,容易证明这个虚点的度数是偶数。那么我们所构造的这张图就满足存在欧拉回路的基本条件了,所以可以直接跑欧拉回路求解。

时间复杂度(O(n+v))(v)是值域)。

代码:

#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=200000;
int n;
int head[Maxn<<1|5],arrive[Maxn<<2|5],nxt[Maxn<<2|5],tot;
void add_edge(int from,int to){
	arrive[++tot]=to;
	nxt[tot]=head[from];
	head[from]=tot;
}
int col[Maxn<<1|5];
int deg[Maxn<<1|5];
void dfs(int u){
	for(int& i=head[u];i;i=nxt[i]){
		int v=arrive[i];
		if(col[(i+1)>>1]){
			continue;
		}
		col[(i+1)>>1]=1+(u<=Maxn);
		dfs(v);
	}
}
int main(){
	read(n);
	for(int i=1;i<=n;i++){
		int u,v;
		read(u),read(v);
		add_edge(u,v+Maxn);
		add_edge(v+Maxn,u);
		deg[u]++,deg[v+Maxn]++;
	}
	for(int i=1;i<=(Maxn<<1);i++){
		if(deg[i]&1){
			add_edge(i,(Maxn<<1|1));
			add_edge((Maxn<<1|1),i);
		}
	}
	for(int i=1;i<=Maxn;i++){
		dfs(i);
	}
	for(int i=1;i<=n;i++){
		if(col[i]==1){
			putchar('b');
		}
		else{
			putchar('r');
		}
	}
	puts("");
	return 0;
}
原文地址:https://www.cnblogs.com/withhope/p/13596237.html