码迷,mamicode.com
首页 > 其他好文 > 详细

Codeforces Round# 305 (Div 1)

时间:2016-04-03 15:51:31      阅读:111      评论:0      收藏:0      [点我收藏+]

标签:

[Codeforces 547D]

题目大意:平面上有n个点,你需要给他们一一染色,可以染‘b‘(blue)或‘r‘(red),要求每一行和每一列所染色的(红色-蓝色)数目的绝对值<=1,输出染色方案。

n ≤ 2 * 10^5

 

 

QAQ虽然说一看就知道是网络流但是数据范围也是吓我一跳QAQ

然而YY半天建图无果。。

首先行和列示要看成点的,给的每一个点(x, y)看成一条边无疑,容量为1

然后广告犇提出了限流思想:既然每行或每列不能相差超过1,那么就可以从源点->每一行连接容量为(cntx[i] / 2)的边,这样红蓝就一定符合条件了!(其中cntx[i]表示第i行有多少个点),从每一列连向汇点同理QAQ

但是这样输出的方案可能还不够,有一些点仍然没有确定怎么办?(假如某一行某一列的点的个数为奇数。。)

然后就弃疗了

orz了一下神犇的题解(虽然说并不知道神犇是谁,但是网络流竟然可以过QAQ)

先把行列离散化一下QAQ,然后如上建边,然后跑一边最大流,然后如果有多出来的就再添加一条容量为1的边,再跑一遍最大流。最后如果割掉了(edge[i<<1])说明此点和S相连,否则和T相连。

某犇:我快YY出正解了

主要程序:(网络流就不写了QAQ)

int main(){
	scanf("%d", &n);
	for(int i = 1; i <= n; i ++)
	    scanf("%d%d", &x[i], &y[i]);
    for(int i = 1; i <= n; i ++)
        ++ cx[x[i]], ++ cy[y[i]];
	int id = 0;
	for(int i = 1; i <= 200000; i ++)
		if(cx[i])Idx[i] = ++ id;
    for(int i = 1; i <= 200000; i ++)
		if(cy[i])Idy[i] = ++ id;
	T = id + 1;
	for(int i = 1; i <= n; i ++)
	    add(Idx[x[i]], Idy[y[i]], 1);
	for(int i = 1; i <= 200000; i ++)
		if(cx[i] > 1) add(S, Idx[i], cx[i] >> 1);
    for(int i = 1; i <= 200000; i ++)
		if(cy[i] > 1) add(Idy[i], T, cy[i] >> 1);
	
	Dinic();
	for(int i = 1; i <= 200000; i ++)
	    if(cx[i] & 1) add(S, Idx[i], 1);
    for(int i = 1; i <= 200000; i ++)
	    if(cy[i] & 1) add(Idy[i], T, 1);
	Dinic();
	for(int i = 1; i <= n; i ++)
	    if(!edge[i<<1].w)
			putchar(‘b‘);
		else putchar(‘r‘);
	puts("");
	return 0;
}

  

Codeforces Round# 305 (Div 1)

标签:

原文地址:http://www.cnblogs.com/Candyouth/p/5349825.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!