【題意】
給出n對情侶的位置,圍成環,現在需要分配食物,使得每個人都是1或2,滿足任意
一對情侶間的食物不同,連着三個人的食物不能全相同。
請給出任意一種分配方案,若不存在輸出-1。
【分析】
每個人相當於節點,每個節點有兩種選擇,然後很自然的想到了01染色,第一個約
束條件是情侶之間選擇不同,即情侶之間連一條邊,第二個條件是連着的三個人食
物不能全相同,也就是任意的三個節點至少有一對相鄰節點不相同,所以我們把這
個圓圈的點依次連邊,即(1, 2)、(3, 4),(4,5)….連邊。
但是這樣連邊與原題中的約束條件等價嗎?我們可以保證,這樣連邊以後跑出來的
方案一定是滿足題意的,但是會不會存在出現無解的情況呢?顯然,我們這樣連邊
每個節點的度數都爲2,即整個圖是由若干個環組成的,並且不存在奇數點環(同一
個環內包含若干對情侶),這樣01染色肯定是存在方案的
#include<cstdio>
#include<iostream>
#include<cstring>
#include<vector>
using namespace std;
const int N = 100000 + 500;
int x[N * 2], y[N * 2];
vector<int> s[N * 2];
int f[N * 2];
void dfs(int x, int col)
{
for(int i = 0; i < s[x].size(); i++){
int y = s[x][i];
if (!f[y]){
f[y] = 3 - col;
dfs(y, 3 - col);
}
}
}
int main()
{
int n ;
scanf("%d", &n);
for(int i = 1; i <= n; i++){
scanf("%d%d", &x[i], &y[i]);
s[x[i]].push_back(y[i]);
s[y[i]].push_back(x[i]);
}
for(int i = 1; i <= n; i++){
s[i << 1].push_back((i << 1) - 1);
s[(i << 1) - 1].push_back(i << 1);
}
for(int i = 1; i <= 2 * n; i++)
if (!f[i])
{
f[i] = 1;
dfs(i, 1);
}
for(int i = 1; i <= n; i++){
printf("%d %d\n", f[x[i]], f[y[i]]);
}
return 0;
}