Problem

Description

幼儿园里有 \(n\) 个小朋友打算通过投票来决定睡不睡午觉。对他们来说,这个问题并不是很重要,于是他们决定发扬谦让精神。虽然每个人都有自己的主见,但是为了照顾一下自己朋友的想法,他们也可以投和自己本来意愿相反的票。我们定义一次投票的冲突数为好朋友之间发生冲突的总数加上和所有和自己本来意愿发生冲突的人数。

我们的问题就是,每位小朋友应该怎样投票,才能使冲突数最小?

Input Format

文件的第一行只有两个整数 \(n,m\),保证有 \(2\le n\le 300,1\le m\le \frac{n(n-1)}{2}\)。其中 \(n\) 代表总人数,m代表好朋友的对数。文件第二行有 \(n\) 个整数,第 \(i\) 个整数代表第 \(i\) 个小朋友的意愿,当它为 \(1\) 时表示同意睡觉,当它为 \(0\) 时表示反对睡觉。接下来文件还有 \(m\) 行,每行有两个整数 \(i\) ,\(j\) 。表示 \(i\) ,\(j\) 是一对好朋友,我们保证任何两对 \(i\) ,\(j\) 不会重复。

Output Format

只需要输出一个整数,即可能的最小冲突数。

Sample

Input 1

3 3
1 0 0
1 2
1 3
3 2

Output 1

1

Range

\(2\le n\le 300, 1\le m\le n(n - 1) / 2\)

Algorithm

网络流

Mentality

先建立一个源点 \(S\) 和汇点 \(T\) ,然后将所有同意睡觉的人和 \(S\) 连边,否则和 \(T\) 连边,容量设为 \(1\) ,再将每对朋友之间连上一条容量为 \(1\) 的边。

若割去一条边的代价为 \(1\) ,不难发现题目所求其实际上就是使 \(S\) 与 \(T\) 之间不连通的最小代价,因为若 \(S\) 和 \(T\) 仍联通,说明它们之间仍有朋友的冲突没有被解决或是被计算。

若断去一个人与其朋友之间的边,就代表他没有违背自己的意愿,而若他断掉与自己所连的源、汇点之间的边,则代表他向朋友妥协了。

跟据最大流等于最小割,直接在建出的图上跑最大流即可。

Code

#include <cstdio>
#include <cstring>
#include <iostream>
#include <queue>
using namespace std;
#define LL long long
#define go(x, i, v) for (int i = hd[x], v = to[i]; i; v = to[i = nx[i]])
#define inline __inline__ __attribute__((always_inline))
inline LL read() {
LL x = 0, w = 1;
char ch = getchar();
while (!isdigit(ch)) {
if (ch == '-') w = -1;
ch = getchar();
}
while (isdigit(ch)) {
x = (x << 3) + (x << 1) + ch - '0';
ch = getchar();
}
return x * w;
}
const int Max_n = 305, Max_m = Max_n * Max_n << 1, inf = 1e9;
int n, m, S, T, ans;
int cntr = 1, hd[Max_n], cur[Max_n], nx[Max_m], to[Max_m], w[Max_m];
int dep[Max_n], fnow[Max_n], flow[Max_n];
void addr(int u, int v, int W) {
cntr++;
nx[cntr] = hd[u], to[cntr] = v, w[cntr] = W;
hd[u] = cntr;
}
queue<int> q;
bool build() {
for (int i = 1; i <= n + 2; i++) cur[i] = hd[i], dep[i] = -1, fnow[i] = 0;
q.push(S), dep[S] = 0, fnow[S] = 1e9;
while (!q.empty()) {
int x = q.front();
q.pop();
go(x, i, v) if (dep[v] == -1 && w[i]) dep[v] = dep[x] + 1, q.push(v);
}
return dep[T] != -1;
}
void dfs(int x) {
if (x == T) {
flow[x] = fnow[x], ans += flow[x];
return;
}
for (int i = cur[x], v = to[i]; i; v = to[i = nx[i]])
if (dep[v] == dep[x] + 1 && w[i]) {
cur[x] = i, fnow[v] = min(fnow[x], w[i]), dfs(v);
w[i] -= flow[v], fnow[x] -= flow[v];
w[i ^ 1] += flow[v], flow[x] += flow[v];
flow[v] = 0;
}
}
int main() {
#ifndef ONLINE_JUDGE
freopen("2057.in", "r", stdin);
freopen("2057.out", "w", stdout);
#endif
n = read(), m = read(), S = n + 1, T = n + 2;
for (int i = 1; i <= n; i++)
if (!read())
addr(S, i, 1), addr(i, S, 0);
else
addr(i, T, 1), addr(T, i, 0);
int u, v;
while (m--) {
u = read(), v = read();
addr(u, v, 1), addr(v, u, 0);
addr(u, v, 0), addr(v, u, 1);
}
while (build()) dfs(S);
cout << ans;
}

【SHOI 2007】善意的投票的更多相关文章

  1. [SHOI 2007] 善意的投票

    [题目链接] https://www.lydsy.com/JudgeOnline/problem.php?id=1934 [算法] 首先 , 选择睡觉的人和不选择睡觉的人构成两个集合 这启发我们用最小 ...

  2. [SHTSC 2007] 善意的投票

    我就是来复习Dinic算法的,仅10天不写,我已经退化成写一遍+调试需要接近一个小时了,当然其中不乏在网上乱逛的时间… 赞成从S源点连一条单向边,反对向T汇点连一条单向边,朋友关系连双向边. 但是总感 ...

  3. 「SHOI2007」「Codevs2341」 善意的投票(最小割

    2341 善意的投票 2007年省队选拔赛上海市队选拔赛 时间限制: 5 s 空间限制: 128000 KB 题目等级 : 大师 Master   题目描述 Description 幼儿园里有n个小朋 ...

  4. C++之路进阶——bzoj1934(善意的投票)

    F.A.Qs Home Discuss ProblemSet Status Ranklist Contest ModifyUser  hyxzc Logout 捐赠本站 Notice:由于本OJ建立在 ...

  5. BZOJ-1934 Vote 善意的投票 最大流+建图

    1934: [Shoi2007]Vote 善意的投票 Time Limit: 1 Sec Memory Limit: 64 MB Submit: 1551 Solved: 951 [Submit][S ...

  6. bzoj1934: [Shoi2007]Vote 善意的投票

    最大流..建图方式都是玄学啊.. //Dinic是O(n2m)的. #include<cstdio> #include<cstring> #include<cctype& ...

  7. BZOJ 1934: [Shoi2007]Vote 善意的投票 最小割

    1934: [Shoi2007]Vote 善意的投票 Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://www.lydsy.com/JudgeOnl ...

  8. 1934: [Shoi2007]Vote 善意的投票

    1934: [Shoi2007]Vote 善意的投票 Time Limit: 1 Sec  Memory Limit: 64 MBSubmit: 1174  Solved: 723[Submit][S ...

  9. 【BZOJ1934】善意的投票(网络流)

    [BZOJ1934]善意的投票(网络流) 题面 Description 幼儿园里有n个小朋友打算通过投票来决定睡不睡午觉.对他们来说,这个问题并不是很重要,于是他们决定发扬谦让精神.虽然每个人都有自己 ...

  10. BZOJ_1934_[Shoi2007]Vote 善意的投票

    BZOJ_1934_[Shoi2007]Vote 善意的投票 Description 幼儿园里有n个小朋友打算通过投票来决定睡不睡午觉.对他们来说,这个问题并不是很重要,于是他们决定发扬谦让精神.虽然 ...

随机推荐

  1. 小程序api的promise封装

    微信小程序和支付宝小程序的api封装方法是一样的,都是外部新建一个js,使用module.exports导出,要注意的是,最好使用post请求,虽然get请求没什么不好,主要是好修改.这里使用的MD5 ...

  2. 微信中使用popup等弹窗组件时点击输入框input键盘弹起导致IOS中按钮无效处理办法

    因为在IOS微信中在弹窗中使用input使键盘弹起,使弹窗的位置上移,当键盘关闭时页面还在上面,弹窗位移量也在上面,只有下拉才能回到原位,这样弹窗也消失了.我的处理办法就是在键盘弹起和消失的时候,让页 ...

  3. Service Mesh 是新瓶装旧酒吗?

    点击下载<不一样的 双11 技术:阿里巴巴经济体云原生实践> 本文节选自<不一样的 双11 技术:阿里巴巴经济体云原生实践>一书,点击上方图片即可下载! 作者 | 李云(花名: ...

  4. 程序员的算法课(20)-常用的图算法:最小生成树(MST)

    版权声明:本文为博主原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明. 本文链接:https://blog.csdn.net/m0_37609579/article/de ...

  5. bs4-爬取小说

    bs4 bs4有两种运行方式一种是处理本地资源,一种是处理网络资源 本地 from bs4 import BeautifulSoup if __name__ == '__main__': fr = o ...

  6. MVC WebApi 返回字符串

    [HttpGet] public HttpResponseMessage GetWebConfigValue(string key) { var response = Request.CreateRe ...

  7. 微信小程序——详细讲解页面传值(多种方法)

    1.使用navigator的url带参传值 (1)在pageA页面有一个固定的值要传递到pageB页面,比如说一个固定的值user_id要传递给B <navigator url=".. ...

  8. lerna式升级

    有段时间没更新博客了,是时候更新一波了. 之前不是vue-next出了吗,然后就去学习了一下,发现整个目录不是那么熟悉了,变成这样了: 于是就这个线索去研究了一下,发下这是用的 lerna + yar ...

  9. Python中的Tcp协议应用之TCP服务端-协程版(推荐)

    利用gevent第三方库,实现协程. 通过协程实现一个服务端服务多个客户端需求. 使用协程的好处是协程比线程更加节省内存资源. gevent安装命令: pip3 install gevent 注意:在 ...

  10. 【原创】003 | 搭上基于SpringBoot事务思想实战专车

    前言 如果这是你第二次看到师长,说明你在觊觎我的美色! 点赞+关注再看,养成习惯 没别的意思,就是需要你的窥屏^_^ 专车介绍 该趟专车是开往基于Spring Boot事务思想实战的专车,在上一篇 搭 ...