CF 741C.Arpa’s overnight party and Mehrdad’s silent entering

IIIIIIV發表於2020-12-06

連結

~~ 果然圖的問題都是難在建圖~~
又虐單身狗

題意:

有n對情侶(2n個人)圍成一圈坐在桌子邊上, 每個人佔一個座位,要求情侶不能吃一樣的食物,並且桌子上相鄰的三個人的食物必須有兩個是不同的,只有兩種食物(1,2),給出一種可行的分配方式。1 <= n <= 1e5。

思路:

由題意可知,食物只有兩種且情侶不能吃一樣的食物,相鄰的三個人的食物必須有兩個是不同的, 就可以想到二分圖。

  • 如果給不能吃同樣食物的兩個人連一條邊,問題就變成了二分圖黑白染色
  • 所以情侶之間需要連一條邊。
  • 剩下來就是解決相鄰三個人的問題了:
  • 讓第2i 與 第2i + 1的人吃不一樣的食物即可(即1連2, 3連4, 5連6 …)
  • 這樣可定是個二分圖 – 2i 和2i - 1 分別連了他們情侶,情侶分別連他們的鄰居,鄰居再連他們的情侶…每次都是給這可能存在的環加兩個點,所以環一定不是奇環。
    建完圖後二分圖染色就好了

程式碼

#include <iostream>
#include <cstring>
#include <algorithm>
#include <vector>
using namespace std;
typedef pair<int, int> PII;
const int maxn = 3e5 + 7;
int h[maxn], e[maxn<<1], ne[maxn<<1], cnt;
int color[maxn<<1];
void add(int u, int v){
	e[cnt] = v;
	ne[cnt] = h[u];
	h[u] = cnt ++;
	e[cnt] = u;
	ne[cnt] = h[v];
	h[v] = cnt ++;
}
void dfs(int u, int c){
	color[u] = c;
	for (int i = h[u]; ~i; i = ne[i]){
		int v = e[i];
		if (color[v]) continue;
		dfs(v, 3 - c);
	}
}
vector<PII> p;
int main(){
	
	int n;
	scanf ("%d", &n);
	for (int i = 0; i <= 2*n; i ++ ) h[i] = -1;
	for (int i = 1; i <= 2*n; i += 2 ) add(i, i + 1);
	for (int i = 1, u, v; i <= n; i ++ ){
		scanf ("%d%d", &u, &v);
		add(u, v);
		p.push_back({u,v});
	}
	for (int i = 1; i <= 2 * n; i ++ ){
		if (!color[i]) dfs(i, 1);
	}
	for (int i = 0; i < n; i ++ ){
		printf ("%d %d\n", color[p[i].first], color[p[i].second]);
	}
	return 0;
} 

相關文章