CF547D Mike and Fish 欧拉回路

原题:https://www.luogu.org/problemnew/show/CF547D

题解:给你n个点染成红或蓝色,使每一行,列的b,r数量不超过1。考虑建图把横纵坐标连在一起这样就能保证行列有连通性。假设建完图正好是个欧拉回路,则入度等于出度,且所有的度数都是偶数,可以将入度染出b出度染成r,这样就能保证b,r,配对。

但若有不是欧拉回路,就要想办法构造,将所有奇数点两两配对,构成欧拉回路就行了。

#include
#define N 200010
using namespace std;
struct E{int to,next;}data[N<<2]; 
inline int rd(){
	int x=0;int f=1;char s=getchar();
	while(!isdigit(s)) f=(s=='-'?-1:f),s=getchar();
	while(isdigit(s)) x=(x<<1)+(x<<3)+s-'0',s=getchar();
	return x*f;
}
int n,len,h[N<<1],p[N<<1],vis[N<<2];
inline void ins(int x,int y){
	data[++len].to=y;data[len].next=h[x];h[x]=len;
	data[++len].to=x;data[len].next=h[y];h[y]=len;
} 
void dfs(int x){
	for(int&i=h[x];i;i=data[i].next){
		int y=data[i].to;
		if(vis[i] || vis[i^1]) continue;
		vis[i]=1;dfs(y);
	} 
}
int main(){
//	freopen("cf547d.in","r",stdin);
	n=rd();len=1;
	for(int i=1;i<=n;i++) {
		int x=rd();int y=rd()+2e5;
		ins(x,y);p[x]++;p[y]++; 
	}
	for(int i=1,last=0;i<=4e5;i++){
		if(p[i]&1)
			if(last) ins(last,i),last=0;
			else last=i;
	} 
	for(int i=1;i<=4e5;i++) if(p[i]) dfs(i);
	for(int i=1;i<=n;i++) putchar(vis[i<<1]?'b':'r');
	return 0;
}

 

你可能感兴趣的:(欧拉回路,CF,图论)