HDU 6126 Give out candies(网络流)
题目给出n,m,k
然后给出n*m的矩阵a[i][j]代表第i个人在获得j 颗糖果能得到的满足值,
然后k是k行每行输入三个整数x,y,z ,x,y,z表示一组限制表示第x个人分到的糖数减去第y个人分到的糖数不大于z;
数据小,考虑网络流(*^_^*)
因为题目的z可能为负数,而网络流建边容量时的负数概念不能被覆盖,所有建立一个等效‘0’位置的值,sign=1000(大于负数绝对值就行)
对于每个人,我们把他拆成m个点,源点向第一个点连inf流量的边,而剩余的点连sign-a[][]中存的值,最后一个a[][]则连被分出来的点到超级汇点;
先不考虑限制条件,我们现在建边所跑出来的最大流并非每个人的最小满足值之和,因为我们建容量时sign-a[][];而n*sign-maxflow则是每个人的最大满足值之和
而题目又有限制条件,所有把满足的按容量inf连,具体看代码,得到答案就是我们上面说的那个
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<queue>
#define mem0(a) memset(a,0,sizeof(a))
#define meminf(a) memset(a,0x3f,sizeof(a))
using namespace std;
typedef long long ll;
typedef long double ld;
typedef double db;
const int maxn=55,maxk=100005,inf=0x3f3f3f3f; int a[maxn][maxn];
int head[maxn*maxn],dist[maxn*maxn],current[maxn*maxn];
int num; struct Edge {
int from,to,flow,pre;
};
Edge edge[maxk]; void addedge(int from,int to,int flow) {
edge[num]=(Edge){from,to,flow,head[from]};
head[from]=num++;
edge[num]=(Edge){to,from,0,head[to]};
head[to]=num++;
} bool bfs (int n) {
queue<int> q;
q.push(0);
memset(dist,-1,sizeof(dist));
dist[0]=0;
while (!q.empty()) {
int now=q.front();
q.pop();
for (int i=head[now];i!=-1;i=edge[i].pre) {
int to=edge[i].to;
if (dist[to]==-1&&edge[i].flow>0) {
dist[to]=dist[now]+1;
q.push(to);
}
}
}
return dist[n]!=-1;
} int dfs(int now,int flow,int n) {
int f;
if (now==n) return flow;
for (int i=current[now];i!=-1;i=edge[i].pre) {
int to=edge[i].to;
current[now]=i;
if (dist[now]+1==dist[to]&&edge[i].flow>0&&
(f=dfs(to,min(flow,edge[i].flow),n))) {
edge[i].flow-=f;
edge[i^1].flow+=f;
return f;
}
}
return 0;
} int dinic(int n) {
int sum=0,f;
while (bfs(n)) {
memcpy(current,head,sizeof(head));
while (f=dfs(0,inf,n)) sum+=f;
}
return sum;
} int main() {
int cas;
scanf("%d",&cas);
while (cas--) {
int n,m,k,i,j,x,y,z;
memset(head,-1,sizeof(head));
num=0;
scanf("%d%d%d",&n,&m,&k);
for (i=1;i<=n;i++) {
scanf("%d",&a[i][1]);
addedge(0,(i-1)*m+1,1e7);
for (j=2;j<=m;j++) {
scanf("%d",&a[i][j]);
addedge((i-1)*m+j-1,(i-1)*m+j,1000-a[i][j-1]);
}
addedge(i*m,n*m+1,1000-a[i][m]);
}
for (i=1;i<=k;i++) {
scanf("%d%d%d",&x,&y,&z);
for (j=max(z+1,1);j<=m&&j-z<=m;j++) {
addedge((x-1)*m+j,(y-1)*m+j-z,1e7);
}
if (j-z>m&&j<=m)
addedge((x-1)*m+j,n*m+1,1e7);
}
int ans=dinic(n*m+1);
if (ans>1e7) printf("-1\n"); else printf("%d\n",n*1000-ans);
}
return 0; }
HDU 6126 Give out candies(网络流)的更多相关文章
- hdu 6126 Give out candies
hdu 6126 Give out candies(最小割) 题意: 有\(n\)个小朋友,标号为\(1\)到\(n\),你要给每个小朋友至少\(1\)个且至多\(m\)个的糖果.小朋友们共提出\(k ...
- HDU 6126.Give out candies 最小割
Give out candies Time Limit: 6000/3000 MS (Java/Others) Memory Limit: 524288/524288 K (Java/Other ...
- HDU 3081 Marriage Match II (网络流,最大流,二分,并查集)
HDU 3081 Marriage Match II (网络流,最大流,二分,并查集) Description Presumably, you all have known the question ...
- HDU 3338 Kakuro Extension (网络流,最大流)
HDU 3338 Kakuro Extension (网络流,最大流) Description If you solved problem like this, forget it.Because y ...
- HDU 4280 Island Transport(网络流,最大流)
HDU 4280 Island Transport(网络流,最大流) Description In the vast waters far far away, there are many islan ...
- Hdu 5407 CRB and Candies (找规律)
题目链接: Hdu 5407 CRB and Candies 题目描述: 给出一个数n,求lcm(C(n,0),C[n,1],C[n-2]......C[n][n-2],C[n][n-1],C[n][ ...
- HDU 6085 - Rikka with Candies | 2017 Multi-University Training Contest 5
看了标程的压位,才知道压位也能很容易写- - /* HDU 6085 - Rikka with Candies [ 压位 ] | 2017 Multi-University Training Cont ...
- 【HDU 6126】Give out candies 最小割
题意 有$n$个小朋友,给每个人分$1~m$个糖果,有k个限制 限制形如$(x,y,z)$ 表示第$x$个人分到的糖数减去第$y$个人分到的糖数不大于$z$,给第$i$个人$j$颗糖获 ...
- HDU 4888 Redraw Beautiful Drawings 网络流 建图
题意: 给定n, m, k 以下n个整数 a[n] 以下m个整数 b[n] 用数字[0,k]构造一个n*m的矩阵 若有唯一解则输出这个矩阵.若有多解输出Not Unique,若无解输出Impossib ...
随机推荐
- 201771010123汪慧和《面向对象程序设计Java》第十三周实验总结
一.理论部分 1.GUI为用户提供交互式的图形化操作界面. (1)提供了程序的外观和感觉.(2)程序利用图形用户界面接受用户的输入,向用户输出程序运行的结果. 2.Java有专门的类库生成各种标准图 ...
- Codeforces 1299B/1300D - Aerodynamic
题目大意: 给定一个图形S,让这个图形任意平移,但是要保证原点(0,0)一直在它的内部或者边上 最后把它能移动到的所有位置进行拼合可以得到一个图形T 问图形S与图形T是否相似 点会按照逆时针顺序给出 ...
- Java算法练习——寻找两个有序数组的中位数
题目链接 题目描述 给定两个大小为 m 和 n 的有序数组 nums1 和 nums2. 请你找出这两个有序数组的中位数,并且要求算法的时间复杂度为 $O(log(m + n))$. 你可以假设 nu ...
- 18 12 14 python提高 装饰器
---恢复内容开始--- 装饰器还真的有些没看懂 一个任意传参的装饰器 一个通用装饰器 def set_func(func): print("------开始进行装饰") # ...
- 日志处理中一些shell命令技巧
日志处理中一些shell命令技巧 阴差阳错的做的日志分析,前途未卜的这段日子,唯一还有点意思的可能就是手动的处理大量日志.总结一下. 日志文件的输入是动则几个G的文本.从N个这样的文件中得到一个列表, ...
- CNN:卷积输出分辨率计算
卷积是CNN非常核心的操作,CNN主要就是通过卷积来实现特征提取的,在卷积操作的计算中会设计到几个概念:步长(strides).补充(padding).卷积核(kernel)等,那卷积的输出分辨率计算 ...
- Win10教育版VL版kms密钥激活
1.右键开始图标,或者win+x,选择Windows PowerShell(管理员): 2.依次执行下面的命令,分别表示安装win10教育版密钥,设置kms服务器,激活win10教育版: slmgr ...
- pycharm使用常见设置
字体修改: file——setting——Editor——font(快捷键:ctrl+alt+s) 修改项目编译器:a,b方法二选一 a.ctrl+alt+s,调出设置窗口——选中想要换的版本即可,如 ...
- idea新建文件模板 (以xml文件为例)
https://blog.csdn.net/li1325169021/article/details/93158207 偷个懒
- Python笔记_第四篇_高阶编程_正则表达式_1.正则表达式简介(re模块)
1. 从一个判断手机号的问题引入: 如果给你一个字符串,去判断是否是一个手机号码,我们通过之前的学习可以有如下代码: # 如果用普通的方式去检验一个电话号码非常麻烦. def checkPhone(s ...