【HDU 6126】Give out candies 最小割
题意
有$n$个小朋友,给每个人分$1~m$个糖果,有k个限制 限制形如$(x,y,z)$ 表示第$x$个人分到的糖数减去第$y$个人分到的糖数不大于$z$,给第$i$个人$j$颗糖获得的满意度为$w_{i,j}$,问总满意度最大值
点$(i,j)$表示第$i$个人分$j$个糖,当这个点属于$s$集合成立,因为是求满意度最大值,所以负权建边,同时加上个最大值$Max$使得满足最大流模板,假设不考虑限制,对于每一个$i$,连边$(i,j)\rightarrow (i,j+1),j\in[1,m)$,边权为$Max-w_i,j$,$s\rightarrow(i,1)$,那么此时的最小割便是能得到最大满意度
对于每个限制,当$x$选了$i$个糖,那么$y$至少要选$i-z$个糖,连边$(x,i)\rightarrow s, i \in [1,m] \land i - z < 1$,或$(x,i)\rightarrow (y,i-z), i \land [1,m] \land 1 \le i - z \le m$ ,或$(x,i)\rightarrow t, i \in [1,m] \land i - z > m$ ,边权为$inf$,这样,当不满足限制的割边发生时,得到的最小割会大于$inf$
关于限制的建边的详细题解:http://blog.csdn.net/wing_wuchen/article/details/77407413
答案为$Max*n-mincut$
代码
#include <bits/stdc++.h>
#define MAXN 300005
#define MAXM 50000005
#define inf 0x3f3f3f3f
using namespace std;
typedef long long LL;
struct Edge {
int to, nxt, c;
}edge[MAXM];
int head[MAXN], cnt = 0;
int d[MAXN], cur[MAXN], pre[MAXN], gap[MAXN];
int source, sink, limit;
void init() {
memset(head, -1, sizeof(head));
cnt = 0;
}
inline void add_edge(int u, int v, int c) {
edge[cnt].to = v;
edge[cnt].nxt = head[u];
edge[cnt].c = c;
head[u] = cnt++;
}
inline void add(int u, int v, int c) {
add_edge(u, v, c); add_edge(v, u, 0);
}
void rev_bfs() {
memset(gap, 0, sizeof(gap));
memset(d, -1, sizeof(d));
d[sink] = 0;
gap[0] = 1;
queue<int> que;
que.push(sink);
while(!que.empty()) {
int u = que.front(); que.pop();
for(int i = head[u]; ~i; i = edge[i].nxt) {
int v = edge[i].to;
if(~d[v])continue;
d[v] = d[u] + 1;
gap[d[v]]++;
que.push(v);
}
}
}
int isap() {
memcpy(cur, head, sizeof(cur));
rev_bfs();
int flow = 0, i;
int u = source;
pre[source] = source;
while(d[sink] < limit) {
if(u == sink) {
int f = inf, neck;
for(i = source; i != sink; i = edge[cur[i]].to) {
if(f > edge[cur[i]].c) {
f = edge[cur[i]].c;
neck = i;
}
}
for(i = source; i != sink; i = edge[cur[i]].to) {
edge[cur[i]].c -= f;
edge[cur[i] ^ 1].c += f;
}
flow += f;
u = neck;
}
for(i = cur[u]; ~i; i = edge[i].nxt) {
if(d[edge[i].to] + 1 == d[u] && edge[i].c) break;
}
if(~i) {
cur[u] = i;
pre[edge[i].to] = u;
u = edge[i].to;
}else {
if((--gap[d[u]]) == 0) break;
int mind = limit;
for(int i = head[u]; ~i; i = edge[i].nxt) {
if(edge[i].c && mind > d[edge[i].to]) {
cur[u] = i;
mind = d[edge[i].to];
}
}
d[u] = mind + 1;
gap[d[u]]++;
u = pre[u];
}
}
return flow;
}
int t, n, m, k, w[100][100], x, y, z;
int get(int x, int y) {return (x - 1) * m + y;}
int main() {
scanf("%d", &t);
while(t--) {
init();
scanf("%d%d%d", &n, &m, &k);
source = 0; sink = n * m + 1; limit = sink + 1;
for(int i = 1; i <= n; ++i) {
add(source, get(i, 1), inf);
for(int j = 1; j <= m; ++j) {
scanf("%d", &w[i][j]);
if(j < m) add(get(i, j), get(i, j + 1), 1000 - w[i][j]);
else add(get(i, j), sink, 1000 - w[i][j]);
}
}
for(int i = 1; i <= k; ++i) {
scanf("%d%d%d", &x, &y, &z);
for(int j = 1; j <= m; ++j) {
if(j - z < 1) add(get(x, j), source, inf);
else if(j - z <= m) add(get(x, j), get(y, j - z), inf);
else add(get(x, j), sink, inf);
}
}
int ans = isap();
if(ans >= inf) printf("-1\n"); else printf("%d\n", 1000 * n - ans);
}
return 0;
}
【HDU 6126】Give out candies 最小割的更多相关文章
- HDU 6126.Give out candies 最小割
Give out candies Time Limit: 6000/3000 MS (Java/Others) Memory Limit: 524288/524288 K (Java/Other ...
- hdu 6126 Give out candies
hdu 6126 Give out candies(最小割) 题意: 有\(n\)个小朋友,标号为\(1\)到\(n\),你要给每个小朋友至少\(1\)个且至多\(m\)个的糖果.小朋友们共提出\(k ...
- HDU 4289:Control(最小割)
http://acm.hdu.edu.cn/showproblem.php?pid=4289 题意:有n个城市,m条无向边,小偷要从s点开始逃到d点,在每个城市安放监控的花费是sa[i],问最小花费可 ...
- HDU 3452 Bonsai(网络流之最小割)
题目地址:HDU 3452 最小割水题. 源点为根节点.再另设一汇点,汇点与叶子连边. 对叶子结点的推断是看度数是否为1. 代码例如以下: #include <iostream> #inc ...
- HDU 5889 Barricade 【BFS+最小割 网络流】(2016 ACM/ICPC Asia Regional Qingdao Online)
Barricade Time Limit: 3000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)Total S ...
- HDU 3526 Computer Assembling(最小割)
http://acm.hdu.edu.cn/showproblem.php?pid=3526 题意:有个屌丝要配置电脑,现在有n个配件需要购买,有两家公司出售这n个配件,还有m个条件是如果配件x和配件 ...
- HDU 6214 Smallest Minimum Cut 最小割,权值编码
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6214 题意:求边数最小的割. 解法: 建边的时候每条边权 w = w * (E + 1) + 1; 这 ...
- HDU 3251 Being a Hero(最小割+输出割边)
Problem DescriptionYou are the hero who saved your country. As promised, the king will give you some ...
- HDU 3691 Nubulsa Expo(全局最小割)
Problem DescriptionYou may not hear about Nubulsa, an island country on the Pacific Ocean. Nubulsa i ...
随机推荐
- 获取服务器classes根路径
/** * 获取web应用路径 * @Description : 方法描述 * @Method_Name : getRootPath * @return * @return : String * @C ...
- nfs部署和优化 -2
客户端: cat /etc/passwd 显示用户 weifeng 500 服务端: vim /etc/exports /mnt 192.168.1.105(rw,sync,all_squash, ...
- 导出txt格式的说明书
/// <summary> /// 说明书 /// </summary> /// <returns></returns> public FileResu ...
- C#各种导入Excel文件的数据的方法总结
在导入前都需要将上传的文件保存到服务器,所以避免重复的写这些代码,先贴出上传文件并保存到服务器指定路径的代码 protected void btnImport_Click(object sender, ...
- No bean named 'cxf' is defined
1.错误描写叙述 严重:Exception starting filter CXFServlet org.springframework.beans.factory.NoSuchBea ...
- css3动画学习资料整理
现在主流浏览器(先不管IE8,IE9吧),尤其是移动端浏览器基本都支持css3了,为了增强页面的表现力,css3动画必不可少了.这篇文章主要整理一下我在学习css3动画所查阅的一些好的资料,并附上两个 ...
- 畅通project再续 HDU杭电1875 【Kruscal算法 || Prim】
Problem Description 相信大家都听说一个"百岛湖"的地方吧.百岛湖的居民生活在不同的小岛中.当他们想去其它的小岛时都要通过划小船来实现.如今政府决定大力发展百岛湖 ...
- HDFS源码分析数据块复制监控线程ReplicationMonitor(一)
ReplicationMonitor是HDFS中关于数据块复制的监控线程,它的主要作用就是计算DataNode工作,并将复制请求超时的块重新加入到待调度队列.其定义及作为线程核心的run()方法如下: ...
- java和erlang之间的DES加解密
app登录,登录的密码要用DES加密,服务器是用erlang,客户端要同时支持多平台(Android.iOS).首先,Java端的DES加密的实现方式, 少说废话了,直接上代码,如下: public ...
- os如何处理键盘的所有按键,显示or不显示,显示是如何显示
[0]README 0.1) source code and text decription are from orange's implemention of a os , and for comp ...