题目描述:
有n对情侣(2n个人)围成一圈坐在桌子边上,每个人占据一个位子,要求情侣不能吃同一
种食物,并且桌子上相邻的三个人的食物必须有两个人是不同的,只有两种食物(1或者是2),问一种可行分配方式。
题解:
如果我们能把不能吃同一种食物的人连边,问题就变成二分图黑白染色
• 所以情侣关系等价于两者之间连一条边
• “每连续的三个人不能都一样”怎么办?
• 让第2i个人和第2i+1个人不能吃一样的食物即可(即1连2,3连4,5连6以此类推)
• 这样肯定是个二分图——2i和2i-1分别连了他两的情侣,情侣又分别连他两的一个邻居……
每次都是给这个可能存在的环加两个点,所以有环就一定不是奇环
蓝边表示情侣连边,红边表示相邻点对隔一对连一条
基础的二分图问题
代码:
#include<bits/stdc++.h>
typedef long long ll;
using namespace std;
inline int read(){int s=0,w=1;char ch=getchar();while(ch<'0'||ch>'9'){if(ch=='-')w=-1;ch=getchar();}while(ch>='0'&&ch<='9') s=s*10+ch-'0',ch=getchar();//s=(s<<3)+(s<<1)+(ch^48);return s*w;
}
const int maxn=5e5+9;
vector<int>edge[maxn];
int a[maxn];
int b[maxn];
int col[maxn];
int vis[maxn];
void dfs(int now,int co)
{vis[now]=1;col[now]=co;for(int i:edge[now]){if(!vis[i]){if(co==1)dfs(i,2);else dfs(i,1); }}
}
int main()
{int n;cin>>n;for(int i=1;i<=n;i++){cin>>a[i]>>b[i];edge[a[i]].push_back(b[i]);edge[b[i]].push_back(a[i]); }for(int i=1;i<=n*2;i=i+2){edge[i].push_back(i+1);edge[i+1].push_back(i);}for(int i=1;i<=2*n;i++){if(!vis[i])dfs(i,1);}for(int i=1;i<=n;i++){printf("%d %d\n",col[a[i]],col[b[i]]);}return 0;
}