Arpa’s overnight party and Mehrdad’s silent entering
大意:
有2n个人围成一圈坐在桌子边上,每个人占据一个位子,对应这2n个人是n对情侣,要求情侣不能吃同一种食物,并且桌子上相邻的三个人的食物必须有两个人是不同的,只有两种食物(1或者是2),问一种可行分配方式。
思路:
因为只有两种颜色,所以是要我们构造一张二分图,其中情侣之间要连边,关键就是如何处理任意三个点之间的关系
题解的思路很巧妙。我们把2i-1与2i之间连边,这样肯定是能保证任意三个点之间不会全部相等
接下来看看如何证明这是一张二分图
一个结论:一张图是二分图的充要条件就是图中不存在奇环
我们会发现,每一个点都被两种边连接,一个来自它的伴侣,一个来自它的其中一个相邻点,所以最后如果有环的话,一定是两种边交替出现的,所以不可能有奇环(一个特殊情况是情侣相邻坐,但不难发现此时也不是奇环)。证毕。
code
#include <bits/c++config.h>
#include <bits/stdc++.h>
#include <cstring>
using namespace std;
#define endl '\n'
#define ll long long
const ll N=2e5+10;
struct ty
{
ll t,l,next;
}edge[N<<1];
ll cn=0;
ll n,a,b;
char c;
ll head[N];
void add_edge(ll a,ll b,ll c)
{
edge[++cn].t=b;
edge[cn].l=c;
edge[cn].next=head[a];
head[a]=cn;
}
ll e1[N],e2[N];
ll col[N];
void dfs(ll id,ll color)
{
if(col[id]!=-1) return;
col[id]=color;
if(color==0) col[id]=2;
for(int i=head[id];i!=-1;i=edge[i].next)
{
ll y=edge[i].t;
dfs(y,color^1);
}
}
void solve()
{
memset(head,-1,sizeof(head));
memset(col,-1,sizeof head);
cin>>n;
for(int i=1;i<=n;++i)
{
cin>>a>>b;
e1[i]=a;e2[i]=b;
add_edge(a,b,1);
add_edge(b,a,1);
}
for(int i=1;i<=n;++i)
{
add_edge(2*i-1,2*i,1);
add_edge(2*i,2*i-1,1);
}
for(int i=1;i<=n*2;++i)
{
if(col[i]==-1) dfs(i,0);
}
for(int i=1;i<=n;++i)
{
cout<<col[e1[i]]<<" "<<col[e2[i]]<<endl;
}
}
int main()
{
ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
solve();
return 0;
}