CF 741C.Arpa’s overnight party and Mehrdad’s silent entering
阿新 • • 發佈:2020-12-07
技術標籤:圖論
~~ 果然圖的問題都是難在建圖~~
題意:
有n對情侶(2n個人)圍成一圈坐在桌子邊上, 每個人佔一個座位,要求情侶不能吃一樣的食物,並且桌子上相鄰的三個人的食物必須有兩個是不同的,只有兩種食物(1,2),給出一種可行的分配方式。1 <= n <= 1e5。
思路:
由題意可知,食物只有兩種且情侶不能吃一樣的食物,相鄰的三個人的食物必須有兩個是不同的, 就可以想到二分圖。
- 如果給不能吃同樣食物的兩個人連一條邊,問題就變成了二分圖黑白染色
- 所以情侶之間需要連一條邊。
- 剩下來就是解決相鄰三個人的問題了:
- 讓第2i 與 第2i + 1的人吃不一樣的食物即可(即1連2, 3連4, 5連6 …)
- 這樣可定是個二分圖 – 2i 和2i - 1 分別連了他們情侶,情侶分別連他們的鄰居,鄰居再連他們的情侶…每次都是給這可能存在的環加兩個點,所以環一定不是奇環。
建完圖後二分圖染色就好了
程式碼
#include <iostream> #include <cstring> #include <algorithm> #include <vector> using namespace std; typedef pair<int, int> PII; const int maxn = 3e5 + 7; int h[maxn], e[maxn<<1], ne[maxn<<1], cnt; int color[maxn<<1]; void add(int u, int v){ e[cnt] = v; ne[cnt] = h[u]; h[u] = cnt ++; e[cnt] = u; ne[cnt] = h[v]; h[v] = cnt ++; } void dfs(int u, int c){ color[u] = c; for (int i = h[u]; ~i; i = ne[i]){ int v = e[i]; if (color[v]) continue; dfs(v, 3 - c); } } vector<PII> p; int main(){ int n; scanf ("%d", &n); for (int i = 0; i <= 2*n; i ++ ) h[i] = -1; for (int i = 1; i <= 2*n; i += 2 ) add(i, i + 1); for (int i = 1, u, v; i <= n; i ++ ){ scanf ("%d%d", &u, &v); add(u, v); p.push_back({u,v}); } for (int i = 1; i <= 2 * n; i ++ ){ if (!color[i]) dfs(i, 1); } for (int i = 0; i < n; i ++ ){ printf ("%d %d\n", color[p[i].first], color[p[i].second]); } return 0; }