【SHOI2009】善意的投票 【题目描述】 幼儿园里有n个小朋友打算通过投票来决定睡不睡午觉。对他们来说,这个问题并不是很重要,于是他们决定发扬谦让精神。虽然每个人都有自己的主见,但是为了照顾一下自己朋友的想法,他们也可以投和自己本来意愿相反的票。我们定义一次投票的冲突数为好朋友之间发生冲突的总数加上和所有和自己本来意愿发生冲突的人数。 我们的问题就是,每位小朋友应该怎样投票,才能使冲突数最小? 【输入】 输入的第一行只有两个整数n,m,保证有2≤n≤300,1≤m≤n(n-1)/2。其中n代表总人数,m代表好朋友的对数。文件第二行有n个整数,第i个整数代表第i个小朋友的意愿,当它为1时表示同意睡觉,当它为0时表示反对睡觉。接下来文件还有m行,每行有两个整数i,j。表示i,j是一对好朋友,我们保证任何两对i,j不会重复。 【输出】 只需要输出一个整数,即可能的最小冲突数。 【输入样例】 3 3 1 0 0 1 2 1 3 3 2 【输出样例】 1 【数据范围】 2≤n≤300,1≤m≤n(n-1)/2。 【题解】 真是天真可爱的幼儿园小朋友~根据题意,每个小朋友其实投什么票都可以,所以只需要考虑所有小朋友各种投票情况下最小的冲突数就好。 联想到最小割,如果能把所有投票方案对应成为一张图就好。虚拟一个源点与所有同意的小朋友相连,再虚拟一个汇点与所有不同意的小朋友相连,每对好友之间连接一条边,所有边流量为1。每次选择一条边就等于选择一个冲突,如果好友之间意见不同就会构成一条增广路,及这个冲突成立。可以证明这张图中的每一组割对应一种投票方案的冲突。 好吧和普通的最小割方案不太一样,这里应用的每一组割只对应一种方案的冲突,感觉不容易想到呢╮(╯﹏╰)╭ (本蒟蒻WA了一次,好友之间的边应该双向流量都为1。) (最开始其实想构图成最短路,因为n很小,所以考虑把每个人拆成两个点,选择冲突的话距离设为1,不过发现总是建不出来,果然我还是太弱了。) 【代码】 Dinic+当前弧优化,数据很弱无压力。 【SHOI2009】善意的投票#代码