【SHOI 2007】善意的投票
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】善意的投票的更多相关文章
- [SHOI 2007] 善意的投票
[题目链接] https://www.lydsy.com/JudgeOnline/problem.php?id=1934 [算法] 首先 , 选择睡觉的人和不选择睡觉的人构成两个集合 这启发我们用最小 ...
- [SHTSC 2007] 善意的投票
我就是来复习Dinic算法的,仅10天不写,我已经退化成写一遍+调试需要接近一个小时了,当然其中不乏在网上乱逛的时间… 赞成从S源点连一条单向边,反对向T汇点连一条单向边,朋友关系连双向边. 但是总感 ...
- 「SHOI2007」「Codevs2341」 善意的投票(最小割
2341 善意的投票 2007年省队选拔赛上海市队选拔赛 时间限制: 5 s 空间限制: 128000 KB 题目等级 : 大师 Master 题目描述 Description 幼儿园里有n个小朋 ...
- C++之路进阶——bzoj1934(善意的投票)
F.A.Qs Home Discuss ProblemSet Status Ranklist Contest ModifyUser hyxzc Logout 捐赠本站 Notice:由于本OJ建立在 ...
- BZOJ-1934 Vote 善意的投票 最大流+建图
1934: [Shoi2007]Vote 善意的投票 Time Limit: 1 Sec Memory Limit: 64 MB Submit: 1551 Solved: 951 [Submit][S ...
- bzoj1934: [Shoi2007]Vote 善意的投票
最大流..建图方式都是玄学啊.. //Dinic是O(n2m)的. #include<cstdio> #include<cstring> #include<cctype& ...
- BZOJ 1934: [Shoi2007]Vote 善意的投票 最小割
1934: [Shoi2007]Vote 善意的投票 Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://www.lydsy.com/JudgeOnl ...
- 1934: [Shoi2007]Vote 善意的投票
1934: [Shoi2007]Vote 善意的投票 Time Limit: 1 Sec Memory Limit: 64 MBSubmit: 1174 Solved: 723[Submit][S ...
- 【BZOJ1934】善意的投票(网络流)
[BZOJ1934]善意的投票(网络流) 题面 Description 幼儿园里有n个小朋友打算通过投票来决定睡不睡午觉.对他们来说,这个问题并不是很重要,于是他们决定发扬谦让精神.虽然每个人都有自己 ...
- BZOJ_1934_[Shoi2007]Vote 善意的投票
BZOJ_1934_[Shoi2007]Vote 善意的投票 Description 幼儿园里有n个小朋友打算通过投票来决定睡不睡午觉.对他们来说,这个问题并不是很重要,于是他们决定发扬谦让精神.虽然 ...
随机推荐
- day01_爬虫和数据
1.什么是爬虫 1.1.爬虫的定义 脚本,程序--->自动抓取万维网上信息的程序. 1.2.爬虫的分类 2.1.通用爬虫 通用网络爬虫 是 捜索引擎抓取系统(Baidu.Google ...
- 附012.Kubeadm部署高可用Kubernetes
一 kubeadm介绍 1.1 概述 参考<附003.Kubeadm部署Kubernetes>. 1.2 kubeadm功能 参考<附003.Kubeadm部署Kubernetes& ...
- 深入浅出Spring(二)
IoC概念 控制反转(Inversion of Control)是一个重要的面向对象编程的法则来削减计算机程序的耦合问题. 它还有一个名字叫做依赖注入(Dependency Injection).Io ...
- CSS浮动和各种定位
CSS定位 css定位机制 文档流:元素按照在HTML中的位置决定排布的过程 块级元素是从上到下的,内联元素是从左到右的 浮动 position布局 position css position属性用于 ...
- SpringBoot使用拦截器、过滤器、监听器
目录 ## 过滤器 PS: 原文链接https://www.cnblogs.com/haixiang/p/12000685.html,转载请注明出处 过滤器简介 过滤器的使用 拦截器 拦截器介绍 使用 ...
- ThinkPHP 中 where条件 or,and 同时使用
('a'=1 and 'b'=2) or ('c'=3 and 'd'=4) and 'e'=5 $where_1['a'] = 1; $where_1['b'] = 2; $where_2['c'] ...
- Java泛型之上、下界通配符的理解(适合初学)
泛型的由来 为什么需要泛型 Java的数据类型一般都是在定义时就需要确定,这种强制的好处就是类型安全,不会出现像弄一个ClassCastException的数据给jvm,数据安全那么执行的clas ...
- Flink入门(三)——环境与部署
flink是一款开源的大数据流式处理框架,他可以同时批处理和流处理,具有容错性.高吞吐.低延迟等优势,本文简述flink在windows和linux中安装步骤,和示例程序的运行,包括本地调试环境,集群 ...
- Android多线程之(一)——View.post()篇
前言 提起View.post(),相信不少童鞋一点都不陌生,它用得最多的有两个功能,使用简便而且实用: 1)在子线程中更新UI.从子线程中切换到主线程更新UI,不需要额外new一个Handler实例来 ...
- echarts 堆叠柱状图 + 渐变柱状图
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...