题目给出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(网络流)的更多相关文章

  1. hdu 6126 Give out candies

    hdu 6126 Give out candies(最小割) 题意: 有\(n\)个小朋友,标号为\(1\)到\(n\),你要给每个小朋友至少\(1\)个且至多\(m\)个的糖果.小朋友们共提出\(k ...

  2. HDU 6126.Give out candies 最小割

    Give out candies Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 524288/524288 K (Java/Other ...

  3. HDU 3081 Marriage Match II (网络流,最大流,二分,并查集)

    HDU 3081 Marriage Match II (网络流,最大流,二分,并查集) Description Presumably, you all have known the question ...

  4. HDU 3338 Kakuro Extension (网络流,最大流)

    HDU 3338 Kakuro Extension (网络流,最大流) Description If you solved problem like this, forget it.Because y ...

  5. HDU 4280 Island Transport(网络流,最大流)

    HDU 4280 Island Transport(网络流,最大流) Description In the vast waters far far away, there are many islan ...

  6. 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][ ...

  7. HDU 6085 - Rikka with Candies | 2017 Multi-University Training Contest 5

    看了标程的压位,才知道压位也能很容易写- - /* HDU 6085 - Rikka with Candies [ 压位 ] | 2017 Multi-University Training Cont ...

  8. 【HDU 6126】Give out candies 最小割

    题意 有$n​$个小朋友,给每个人分$1~m​$个糖果,有k个限制 限制形如$(x,y,z)​$ 表示第$x​$个人分到的糖数减去第$y​$个人分到的糖数不大于$z​$,给第$i​$个人$j​$颗糖获 ...

  9. HDU 4888 Redraw Beautiful Drawings 网络流 建图

    题意: 给定n, m, k 以下n个整数 a[n] 以下m个整数 b[n] 用数字[0,k]构造一个n*m的矩阵 若有唯一解则输出这个矩阵.若有多解输出Not Unique,若无解输出Impossib ...

随机推荐

  1. 201771010123汪慧和《面向对象程序设计Java》第十三周实验总结

     一.理论部分 1.GUI为用户提供交互式的图形化操作界面. (1)提供了程序的外观和感觉.(2)程序利用图形用户界面接受用户的输入,向用户输出程序运行的结果. 2.Java有专门的类库生成各种标准图 ...

  2. Codeforces 1299B/1300D - Aerodynamic

    题目大意: 给定一个图形S,让这个图形任意平移,但是要保证原点(0,0)一直在它的内部或者边上 最后把它能移动到的所有位置进行拼合可以得到一个图形T 问图形S与图形T是否相似 点会按照逆时针顺序给出 ...

  3. Java算法练习——寻找两个有序数组的中位数

    题目链接 题目描述 给定两个大小为 m 和 n 的有序数组 nums1 和 nums2. 请你找出这两个有序数组的中位数,并且要求算法的时间复杂度为 $O(log(m + n))$. 你可以假设 nu ...

  4. 18 12 14 python提高 装饰器

    ---恢复内容开始--- 装饰器还真的有些没看懂  一个任意传参的装饰器   一个通用装饰器 def set_func(func): print("------开始进行装饰") # ...

  5. 日志处理中一些shell命令技巧

    日志处理中一些shell命令技巧 阴差阳错的做的日志分析,前途未卜的这段日子,唯一还有点意思的可能就是手动的处理大量日志.总结一下. 日志文件的输入是动则几个G的文本.从N个这样的文件中得到一个列表, ...

  6. CNN:卷积输出分辨率计算

    卷积是CNN非常核心的操作,CNN主要就是通过卷积来实现特征提取的,在卷积操作的计算中会设计到几个概念:步长(strides).补充(padding).卷积核(kernel)等,那卷积的输出分辨率计算 ...

  7. Win10教育版VL版kms密钥激活

    1.右键开始图标,或者win+x,选择Windows PowerShell(管理员): 2.依次执行下面的命令,分别表示安装win10教育版密钥,设置kms服务器,激活win10教育版: slmgr ...

  8. pycharm使用常见设置

    字体修改: file——setting——Editor——font(快捷键:ctrl+alt+s) 修改项目编译器:a,b方法二选一 a.ctrl+alt+s,调出设置窗口——选中想要换的版本即可,如 ...

  9. idea新建文件模板 (以xml文件为例)

    https://blog.csdn.net/li1325169021/article/details/93158207 偷个懒

  10. Python笔记_第四篇_高阶编程_正则表达式_1.正则表达式简介(re模块)

    1. 从一个判断手机号的问题引入: 如果给你一个字符串,去判断是否是一个手机号码,我们通过之前的学习可以有如下代码: # 如果用普通的方式去检验一个电话号码非常麻烦. def checkPhone(s ...