【CF547D】Mike and Fish(黑白染色)
阿新 • • 發佈:2020-11-18
- 給定\(n\)個整點,你需要把每個點染成紅色或藍色。
- 要求同行或同列兩種顏色點數相差不超過\(1\),求一種合法方案。
- \(n\le2\times10^5\)
黑白染色
考慮對於同一行或同一列的點,我們任意讓它們兩兩配對(如果剩下某一個則不管),強制配對的兩點顏色相反,顯然可以滿足條件。
然後發現這是一張二分圖,黑白染色的方案必然存在。
於是就做完了?
程式碼:\(O(n)\)
#include<bits/stdc++.h> #define Tp template<typename Ty> #define Ts template<typename Ty,typename... Ar> #define Reg register #define RI Reg int #define Con const #define CI Con int& #define I inline #define W while #define N 200000 #define add(x,y) (e[++ee].nxt=lnk[x],e[lnk[x]=ee].to=y) using namespace std; int n;vector<int> A[N+5],B[N+5];vector<int>::iterator ti,tj; int ee,c[N+5],lnk[N+5];struct edge {int to,nxt;}e[4*N+5]; I void Col(CI x) {for(RI i=lnk[x];i;i=e[i].nxt) !~c[e[i].to]&&(c[e[i].to]=c[x]^1,Col(e[i].to),0);}//黑白染色 int main() RI i,x,y;for(scanf("%d",&n),i=1;i<=n;++i) scanf("%d%d",&x,&y),A[x].push_back(i),B[y].push_back(i);//存到每行/每列對應的vector裡 for(i=1;i<=N;++i) if(A[i].size()) { ti=tj=A[i].begin(),A[i].size()&1&&(++ti,++tj,0);//個數為奇數就拋棄第一個 W(ti!=A[i].end()) ++tj,add(*ti,*tj),add(*tj,*ti),++ti,++ti,++tj;//任意兩兩配對 } for(i=1;i<=N;++i) if(B[i].size()) { ti=tj=B[i].begin(),B[i].size()&1&&(++ti,++tj,0); W(ti!=B[i].end()) ++tj,add(*ti,*tj),add(*tj,*ti),++ti,++ti,++tj; } for(memset(c,-1,sizeof(c)),i=1;i<=n;++i) !~c[i]&&(c[i]=1,Col(i),0),putchar(c[i]?'r':'b');return 0; }