题目描述
给定平面上的n个整点(xi, yi),相互不重叠。要求将每个点染成红色或者蓝色,使得每行或者每列的红色点数和蓝色点数之差小于或等于1。
输入格式
第1行:1个整数n, 表示整点的数量接下来n(1≤n≤2*10^5)行,每行2个整数xi, yi(1≤x,y≤2*10^5)
输出格式
第1行:输出一个长度为n的字符串,仅包含'r'(红色)或者'b'(蓝色),第i个字符表示第i个点所染的颜色
输入样例
3
1 1
1 2
2 1
输出样例(special judge)
brr
题解:
一列中的x个点连⌊x/2⌋条边,一行中的y点连⌊y/2⌋边,然后交叉染色。说的可能不是很清楚,详见代码。
#include<cstring> #include<cstdio> const int N=200010; int n, x, y, con[2][N], can[N]; char col[2]={ 'r', 'b' }; int fir[N], ecnt; struct node{ int e, next; } edge[N<<1]; void Link( int s, int e ) { edge[++ecnt].e=e; edge[ecnt].next=fir[s]; fir[s]=ecnt; edge[++ecnt].e=s; edge[ecnt].next=fir[e]; fir[e]=ecnt; } void DFS( int s ) { for( int i=fir[s]; i; i=edge[i].next ) if( can[ edge[i].e ]==-1 ) { can[ edge[i].e ]=can[s]^1; DFS( edge[i].e ); } } int main() { scanf( "%d", &n ); for( int i=1; i<=n; i++ ) { scanf( "%d%d", &x, &y ); if( con[0][x] ) Link( con[0][x], i ), con[0][x]=0; else con[0][x]=i; if( con[1][y] ) Link( con[1][y], i ), con[1][y]=0; else con[1][y]=i; } memset( can, -1, sizeof can ); for( int i=1; i<=n; i++ ) if( can[i]==-1 ) can[i]=0, DFS(i); for( int i=1; i<=n; i++ ) printf( "%c", col[ can[i] ] ); return 0; }