http://codeforces.com/contest/741/problem/C
题目描述
要不我就用这次模拟考的题面吧哈哈哈写的好有趣:
七夕节,有 对情侣围做在一个圆桌上吃饭。座位的编号为 1~2n(1<=n<=10^5) 。饭店老板作为大FFF团的一员,看着这一桌,身旁不知何时多了一根火把。 他想了想,觉得火把太暴力了,要让敌人从内部瓦解。于是,他决定让一对情侣两个人一个吃好吃的食物,一个吃难吃的食物,这样他们就会产生分歧,感情出现裂痕…… 同时,任意连续3人也不能都吃到难吃的食物或都吃到好吃的食物。注意:1 和 2n是相邻的。老板现在还沉浸在想出这个妙招的喜悦中,分配食物的方案就交给你了。
输入格式
第一行一个数 ,表示情侣的对数。
接下来 行,每行两个数,分别表示第 对情侣两个人就座的位置。
输入保证每个位置恰好有一个人坐。
输出格式
如果有解,则输出 行,每行两个数,表示第 对情侣两个人的食物。 代表难吃的, 代表好吃的。 无解输出 -1
样例输入
3
1 4
2 5
3 6
样例输出
1 2
2 1
1 2
解法:
这道题有两个突破点:
1、情侣要不同
2、相邻的三个人不能相同
那么我们考虑把每个人看成一个点,构一个图,用黑白染色的方法来让一条边的两端的点不一样。那么怎么构图呢?
显而易见,要满足条件1,对情侣之间连一条无向边即可。
要满足条件2,我们可以对2i和2i-1连一条无向边(也就是1–2,3–4),为什么,举个例子,假如我们现在是1–2,3–4,最坏的情况是2,3相同,但是由于1和2相连,3和4相连所以1和2不同,3和4不同,所以不会有连续三个相同的情况。
#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
struct node
{
int x,y,next;
}t[400010]; int len,last[200010];
void ins(int x,int y)
{
t[++len].x=x;t[len].y=y;
t[len].next=last[x];last[x]=len;
}
int a[200010],b[200010],ans[200010];
void dfs(int x,int w)
{
ans[x]=w;
for(int k=last[x];k;k=t[k].next)
{
int y=t[k].y;
if(!ans[y]) dfs(y,3-w);
}
}
int main()
{
int n; scanf("%d",&n);
for(int i=1;i<=n;i++)
{
scanf("%d%d",&a[i],&b[i]);
ins(a[i],b[i]);
ins(b[i],a[i]);
}
for(int i=1;i<=n;i++)
{
ins(i*2-1,i*2);
ins(i*2,i*2-1);
}
for(int i=1;i<=2*n;i++)
if(!ans[i])
dfs(i,1);
for(int i=1;i<=n;i++)
printf("%d %d\n",ans[a[i]],ans[b[i]]);
return 0;
}