題目鏈接
題意:有N對情侶,他們要圍坐在一個2N大小的圓桌一塊喫飯,有這樣的要求,情侶兩人必須有一個人得要喫好喫的食物,另一個人喫不好喫的,也就是一個人喫食物1,另一個人喫食物2,並且圓桌上任意連續3個人的食物必須不完全相同,也就是不能3個人都是喫1或2的,最後1和2N相鄰(圓桌嘛)。
這就很玄學的一個問題。
首先,對於N對情侶構造出來的關係,其實就是一個2-sat問題,但是同時又存在3點的問題,而3點就是一個比較玄學的東西了,我們試着將3點向2點轉移,再使用2-sat的方式來解決這個問題。
將連續3點不能相同的問題展開出來,會有這樣的幾種情況"AAB"、"ABA"、"BAA"這幾種合法情況,我們再展開加上整體的平移來看,可以將上式看成"ABBA"、"ABAB"這兩種情況,那爲什麼沒有"AABB"呢?因爲"AABB"可以是通過"ABBA"平移完成的。所以,根據這樣的情況,我們做大膽假設只要滿足再加上兩情侶之間的2點關係,就可以滿足題目要求了。
保證每兩個人之間食物種類是不同的,那麼一定有連續三個人的食物種類之中一定是存在至少一對不同的食物。
然後這樣的情況,可能會構成多個聯通塊,所以要判斷一下。
2
1 3
2 4
ans:
1 2
2 1
#include <iostream>
#include <cstdio>
#include <cmath>
#include <string>
#include <cstring>
#include <algorithm>
#include <limits>
#include <vector>
#include <stack>
#include <queue>
#include <set>
#include <map>
#include <bitset>
#include <unordered_map>
#include <unordered_set>
#define lowbit(x) ( x&(-x) )
#define pi 3.141592653589793
#define e 2.718281828459045
#define INF 0x3f3f3f3f
#define Big_INF 0x3f3f3f3f3f3f3f3f
#define HalF (l + r)>>1
#define lsn rt<<1
#define rsn rt<<1|1
#define Lson lsn, l, mid
#define Rson rsn, mid+1, r
#define QL Lson, ql, qr
#define QR Rson, ql, qr
#define myself rt, l, r
#define MP(a, b) make_pair(a, b)
using namespace std;
typedef unsigned long long ull;
typedef unsigned int uit;
typedef long long ll;
const int maxN = 2e5 + 7;
int N, head[maxN], cnt;
pair<int, int> t[maxN];
struct Eddge
{
int nex, to;
Eddge(int a=-1, int b=0):nex(a), to(b) {}
} edge[maxN << 2];
inline void addEddge(int u, int v)
{
edge[cnt] = Eddge(head[u], v);
head[u] = cnt++;
}
inline void _add(int u, int v) { addEddge(u, v); addEddge(v, u); }
int col[maxN] = {0};
bool bfs(int st)
{
queue<int> Q;
Q.push(st); col[st] = 1;
while(!Q.empty())
{
int u = Q.front(); Q.pop();
for(int i=head[u], v; ~i; i=edge[i].nex)
{
v = edge[i].to;
if(col[v])
{
if(col[v] == col[u]) return false;
continue;
}
col[v] = 3 - col[u];
Q.push(v);
}
}
return true;
}
inline void init()
{
cnt = 0;
for(int i=1; i<=(N << 1); i++) head[i] = -1;
}
int main()
{
scanf("%d", &N);
init();
for(int i=1, u, v; i<=N; i++)
{
scanf("%d%d", &u, &v);
_add(u, v);
t[i] = MP(u, v);
}
for(int i=1; i<=N; i++) _add(2 * i, 2 * i - 1);
for(int i=1; i<=(N<<1); i++)
{
if(!col[i])
{
bool ok = bfs(i);
if(!ok) { printf("-1\n"); return 0; }
}
}
for(int i=1; i<=N; i++) printf("%d %d\n", col[t[i].first], col[t[i].second]);
return 0;
}