1. 程式人生 > 實用技巧 >Codeforces 547D. Mike and Fish 題解

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;
}