BZOJ 1934 善意的投票
题目链接:
https://www.lydsy.com/JudgeOnline/problem.php?id=1934
题目大意:
幼儿园里有n个小朋友打算通过投票来决定睡不睡午觉。对他们来说,这个问题并不是很重要,于是他们决定发扬谦让精神。虽然每个人都有自己的主见,但是为了照顾一下自己朋友的想法,他们也可以投和自己本来意愿相反的票。我们定义一次投票的冲突数为好朋友之间发生冲突的总数加上和所有和自己本来意愿发生冲突的人数。 我们的问题就是,每位小朋友应该怎样投票,才能使冲突数最小?
思路:
最小割,所有赞成的与源点连边,所有反对的与汇点连边,朋友之间连边,求最小割即可。
1 #include<bits/stdc++.h> 2 #define IOS ios::sync_with_stdio(false);//不可再使用scanf printf 3 #define Max(a, b) ((a) > (b) ? (a) : (b))//禁用于函数,会超时 4 #define Min(a, b) ((a) < (b) ? (a) : (b)) 5 #define Mem(a) memset(a, 0, sizeof(a)) 6 #define Dis(x, y, x1, y1) ((x - x1) * (x - x1) + (y - y1) * (y - y1)) 7 #define MID(l, r) ((l) + ((r) - (l)) / 2) 8 #define lson ((o)<<1) 9 #define rson ((o)<<1|1) 10 #define Accepted 0 11 #pragma comment(linker, "/STACK:102400000,102400000")//栈外挂 12 using namespace std; 13 inline int read() 14 { 15 int x=0,f=1;char ch=getchar(); 16 while (ch<'0'||ch>'9'){if (ch=='-') f=-1;ch=getchar();} 17 while (ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();} 18 return x*f; 19 } 20 typedef long long ll; 21 const int maxn = 2000 + 10; 22 const int MOD = 1000000007;//const引用更快,宏定义也更快 23 const int INF = 1e9 + 7; 24 const double eps = 1e-6; 25 26 struct edge 27 { 28 int u, v, c, f; 29 edge(int u, int v, int c, int f):u(u), v(v), c(c), f(f){} 30 }; 31 vector<edge>e; 32 vector<int>G[maxn]; 33 int level[maxn];//BFS分层,表示每个点的层数 34 int iter[maxn];//当前弧优化 35 int m; 36 void addedge(int u, int v, int c) 37 { 38 e.push_back(edge(u, v, c, 0)); 39 e.push_back(edge(v, u, 0, 0)); 40 m = e.size(); 41 G[u].push_back(m - 2); 42 G[v].push_back(m - 1); 43 } 44 void BFS(int s)//预处理出level数组 45 //直接BFS到每个点 46 { 47 memset(level, -1, sizeof(level)); 48 queue<int>q; 49 level[s] = 0; 50 q.push(s); 51 while(!q.empty()) 52 { 53 int u = q.front(); 54 q.pop(); 55 for(int v = 0; v < G[u].size(); v++) 56 { 57 edge& now = e[G[u][v]]; 58 if(now.c > now.f && level[now.v] < 0) 59 { 60 level[now.v] = level[u] + 1; 61 q.push(now.v); 62 } 63 } 64 } 65 } 66 int dfs(int u, int t, int f)//DFS寻找增广路 67 { 68 if(u == t)return f;//已经到达源点,返回流量f 69 for(int &v = iter[u]; v < G[u].size(); v++) 70 //这里用iter数组表示每个点目前的弧,这是为了防止在一次寻找增广路的时候,对一些边多次遍历 71 //在每次找增广路的时候,数组要清空 72 { 73 edge &now = e[G[u][v]]; 74 if(now.c - now.f > 0 && level[u] < level[now.v]) 75 //now.c - now.f > 0表示这条路还未满 76 //level[u] < level[now.v]表示这条路是最短路,一定到达下一层,这就是Dinic算法的思想 77 { 78 int d = dfs(now.v, t, min(f, now.c - now.f)); 79 if(d > 0) 80 { 81 now.f += d;//正向边流量加d 82 e[G[u][v] ^ 1].f -= d; 83 //反向边减d,此处在存储边的时候两条反向边可以通过^操作直接找到 84 return d; 85 } 86 } 87 } 88 return 0; 89 } 90 int Maxflow(int s, int t) 91 { 92 int flow = 0; 93 for(;;) 94 { 95 BFS(s); 96 if(level[t] < 0)return flow;//残余网络中到达不了t,增广路不存在 97 memset(iter, 0, sizeof(iter));//清空当前弧数组 98 int f;//记录增广路的可增加的流量 99 while((f = dfs(s, t, INF)) > 0) 100 { 101 flow += f; 102 } 103 } 104 return flow; 105 } 106 int x[maxn]; 107 int main() 108 { 109 int n, m; 110 scanf("%d%d", &n, &m); 111 int s = 0, t = n + 1; 112 for(int i = 1; i <= n; i++) 113 { 114 scanf("%d", &x[i]); 115 if(x[i])addedge(s, i, 1);//所有赞成的与源点连边 116 else addedge(i, t, 1);//所有反对的与汇点连边 117 } 118 while(m--) 119 { 120 int u, v; 121 scanf("%d%d", &u, &v); 122 if(x[u] && !x[v])//u赞成 v反对 123 addedge(u, v, 1); 124 if(x[v] && !x[u])//v赞成 u反对 125 addedge(v, u, 1);//最小割 126 } 127 printf("%d\n", Maxflow(s, t)); 128 return Accepted; 129 }
转载于:https://www.cnblogs.com/fzl194/p/9711467.html
BZOJ 1934 善意的投票相关推荐
- 【BZOJ 1934】 [Shoi2007]Vote 善意的投票
1934: [Shoi2007]Vote 善意的投票 Time Limit: 1 Sec Memory Limit: 64 MB Submit: 1205 Solved: 746 [Submit] ...
- bzoj 1934: [Shoi2007]Vote 善意的投票(最小割)
1934: [Shoi2007]Vote 善意的投票 Time Limit: 1 Sec Memory Limit: 64 MB Submit: 1796 Solved: 1094 [Submit ...
- bzoj1934【shoi2007】Vote善意的投票
1934: [Shoi2007]Vote 善意的投票 Time Limit: 1 Sec Memory Limit: 64 MB Submit: 1533 Solved: 942 [Submit] ...
- P2057 [SHOI2007]善意的投票 (最大流最小割)
P2057 [SHOI2007]善意的投票 / [JLOI2010]冠军调查 最小割,两种意见可以看作源点S和T,我们需要做的是割最少的边使得S和T成为两个不同的集合,解释:割掉的边相当于1次冲突(因 ...
- 洛谷P2057 【SHOI2007】善意的投票
洛谷P2057 [SHOI2007]善意的投票 题目链接 这道题是最小割的一个经典应用:划分集合. 题目的意思就是就是将所有的小朋友分为两个集合:同意睡觉和不同意睡觉的.不同的集合之间的边都要断开. ...
- 【BZOJ2768】[JLOI2010]冠军调查/【BZOJ1934】[Shoi2007]Vote 善意的投票 最小割
[BZOJ2768][JLOI2010]冠军调查 Description 一年一度的欧洲足球冠军联赛已经进入了淘汰赛阶段.随着卫冕冠军巴萨罗那的淘汰,英超劲旅切尔西成为了头号热门.新浪体育最近在吉林教 ...
- 【BZOJ1934】善意的投票(网络流)
[BZOJ1934]善意的投票(网络流) 题面 Description 幼儿园里有n个小朋友打算通过投票来决定睡不睡午觉.对他们来说,这个问题并不是很重要,于是他们决定发扬谦让精神.虽然每个人都有自己 ...
- 51nod Vote 善意的投票
51nod2934 Vote 善意的投票 ☠2.02.02.0 秒 /// ☣262,144.0262,144.0262,144.0 KBKBKB /// ☢808080 分 /// ி555级题 注 ...
- ●BZOJ 1934 [Shoi2007]Vote 善意的投票
题链: http://www.lydsy.com/JudgeOnline/problem.php?id=1934 题解: 题目有点迷. S向为1的点连边,为0的点向T连边, 在有关系的两个点之间连双向 ...
- BZOJ 1934: [Shoi2007]Vote 善意的投票
题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=1934 求图的最小割=求一下图的最大流. #include <iostream> ...
最新文章
- 每日一皮:程序员距离人生目标只有一个沟
- python提取字符串中的 中文 日文 韩文
- python规模_python语言计算生态规模有多大?
- Unity的匹配系统
- grep/egrep和正则表达式汇总
- 以太坊节点开放RPC端口容易被攻击及网络安全配置笔记
- 使用jquery简化ajax开发
- mysql表空间过大_详解MySQL表空间以及ibdata1文件过大问题
- 输出svn版本号到头文件
- 网页扫雷(简易版)(一)
- Python实现双色球随机选号
- 【JY】力荐 | 区域建筑地震安全性有限元分析示例
- 以下不是dns服务器的作用,以下不是DNS服务的作用的是( )。
- 平面设计PS素材网站,强推
- android l root 方法,安卓L怎么Root 新版Android L一键root教程
- Creo 9.0 基准特征:基准点
- Photoshop 入门教程「2」了解 Photoshop 工作区
- Oracle查询数据表数据很少却很慢
- 《大数据: IDEA开发工具配置大全》
- element ui el-table单元格按需合并
热门文章
- string和数值之间的转换
- 公式推导以及代码书写 11-26
- 凸优化有关的数值线性代数知识 1矩阵结构与算法复杂性
- 凸优化第四章凸优化问题 4.7向量优化
- 现代通信原理4.3:白噪声
- DL实战(3):cfNet- Matlab配置
- 凸优化学习笔记(四):对偶性、KKT 条件、敏感性分析
- 计算机图形学完整笔记(五):二维图形变换
- LaTeX 消除字Font shape `OMX/cmex/m/n‘ in size <10.53937> not available (Font)	size <10.95> substituted.
- Linux微信群shell,linux shell基础