P2057冠军调查(最小割思想)
题目大意:小伙伴们一起投票决定睡不睡觉,1表示想睡觉,2表示不想睡觉
小伙伴们之间有一些亲密的朋友关系,小伙伴们想要让最终违背自己的意愿
和以及违背亲密朋友的意愿的和最小,问小伙伴们最终投票下违背意愿
(违背自己或者投票和朋友不同都算)数目最少。
思路:没思路,看的题解...
我们大概都能想到最小割,那么两个对立的集合怎么找出来呢,我们重新思考这个问题,
投票只能为1或者0,那是不是就已经能把学生分为两个对立方了,然后呢,我们再思考,
违背自己的意愿和违背朋友的意愿这个条件,我们发现,如果两个朋友最初的想法不同(所在集合不同),
那么最终结果必定会产生矛盾,也就是要么会违背自己的意愿,要么朋友会违背自己的意愿。
那么我们就可以想出,应该再对朋友之间连双向边,这样就能满足最小割的条件了,口胡完毕。
部分代码:
int n, m; int main() { //freopen("test.txt", "r", stdin); scanf("%d%d", &n, &m); s = n + 1, d = s + 1; for (int i = 1; i <= n; i++) { int q; scanf("%d", &q); if (q) {//按照最初的选择分为两个集合 add(s, i, 1); add(i, s, 0); } else { add(i, d, 1); add(d, i, 1); } } for (int i = 1; i <= m; i++) { int a, b; scanf("%d%d", &a, &b); add(a, b, 1);//朋友之间连双向边 add(b, a, 0); add(b, a, 1); add(a, b, 0); } printf("%lld\n", dinic());//最大瘤 return 0; }