【CQOI2009】跳舞

【CQOI2009】跳舞

【题目描述】

一次舞会有n个男孩和n个女孩。每首曲子开始时,所有男孩和女孩恰好配成n对跳交谊舞。每个男孩都不会和同一个女孩跳两首(或更多)舞曲。 
有一些男孩女孩相互喜欢,而其他相互不喜欢(不会“单向喜欢”)。每个男孩最多只愿意和k个不喜欢的女孩跳舞,而每个女孩也最多只愿意和k个不喜欢的男孩跳舞。 
给出每对男孩女孩是否相互喜欢的信息,舞会最多能有几首舞曲?

【输入】

第一行包含两个整数n和k。以下n行每行包含n个字符,其中第i行第j个字符为“Y”当且仅当男孩i和女孩j相互喜欢。

【输出】

仅一个数,即舞曲数目的最大值。

【输入样例】

3 0
YYY
YYY
YYY

【输出样例】

3

【数据范围】

数据  1        2        3        4        5        6        7        8        9        10
N     1        3        5        8        10       40       40       50       50       50
k     1        2        2        1        4        0        14       10       20       30

【题解】

看题目大概就能猜到是二分图匹配了……

一种想法是把每个男孩/女孩拆分成“喜欢”和“不喜欢”两个点,分别代表和喜欢/不喜欢的人跳舞,然后二分答案检验。但这种做法效率不高,还要去考虑二分上下界,而且代码也会比较冗杂。

换个思路来考虑,既然“喜欢”是相互的,那么就只存在“喜欢关系”,“喜欢”的双方并不重要。假如某个男孩喜欢t个女孩,那等价于这个男孩有t个喜欢关系,可以和t个女孩跳舞,至于这t个女孩是谁并不重要。类似的,“不喜欢关系”也只是一个数目,代表男孩除了t个喜欢的女孩外,还可以和k个女孩跳舞,至于这k个女孩是谁、是否“喜欢”都不必考虑。

以上,建图方案出来了,虚拟一个源点和所有男孩相连,流量为t+k,再虚拟一个汇点与所有女孩相连,流量为t+k(t为男孩/女孩喜欢的人数),再在每对男孩女孩之间连接一条流量为1的边。然后跑最大流,然后输出最大流,然后WA(%>_<%)

数据弱啊,直接输最大流有50分,害得我一直以为是建图有误……实际上最大流不是答案,跑完最大流后得到一个残量网络,然后统计残量网络上所有男孩节点的流入量以及所有女孩节点的流出量的最小值,这才是答案。

【代码】

第二种思路直接上Dinic无压力,完爆第一种思路。

【CQOI2009】跳舞#代码

你可能感兴趣的:(解题报告)