hdu 6126 Give out candies
hdu 6126 Give out candies(最小割)
题意:
有\(n\)个小朋友,标号为\(1\)到\(n\),你要给每个小朋友至少\(1\)个且至多\(m\)个的糖果。小朋友们共提出\(k\)个要求,每个要求包括三个整数\(x,y,z\),表示\(x\)号小朋友得到的糖果数减去\(y\)号小朋友得到的糖果数,结果应当不大于\(z\)。如果你给\(i\)号小朋友\(j\)颗糖果,他会获得\(w_{i,j}\)
的满意度,你需要最大化所有小朋友的满意度之和。\(1\leq n,m\leq50,1\leq k\leq150,1\leq w_{i,j}\leq10^3\)
 。
题解:
用\(i.j\)这点表示给第\(i\)个孩子至少\(j\)块糖,当这个点属于S集合时所代表条件成立。然后\(i.j->i.j+1\)连\(1000-w_{i,j},i.m\)向\(T\)连\(1000-w_{i,m},S\)向\(i.1\)连\(inf\)。如果存在\(a_x-a_y>=z\),\(x.k->y.k+z\)连\(inf\)。跑最小割,再用\(n*1000\)减掉答案。
网络流的题目建模总是很玄的,结合这篇博客理解了一下,虽然还是没有完全领悟。
首先考虑没有限制的情况,那么显然选\(w_{i,j}\)越大越好,按题解建图的方法,令这条边的容量为\(F-w_{i,j}\),F为一个足够大的数,显然最小割会选到这条边。
想象一下 对限制连流量无穷大的边的情况
首先在合法情况下,给一条边的容量设置为无穷大,表示这条边是无法被最小割选到的
如果没有限制,每个人选择方案可以在同侧,连了限制的边后,就限制了选择方案必须在这条边的两侧,这样才能保证能够割到这条无穷大的边,如果跑出来的流量是无穷大的,说明最小割不存在,没有合法选择。
#include<bits/stdc++.h>
using namespace std;
const int maxn = 3000;
const int inf = 0x3f3f3f3f;
struct Edge{
int u,v,cap,flow;
Edge(){};
Edge(int u,int v,int cap,int flow):u(u),v(v),cap(cap),flow(flow){}
};
struct Dinic{
    int n,m,s,t;
    vector<Edge> edges;
    vector<int> G[maxn];
    int vis[maxn],d[maxn],cur[maxn];
    void init(int n){
        this->n = n;
        for(int i = 0;i < n;i++) G[i].clear();
        edges.clear();
    }
    void add(int u,int v,int cap){
        edges.push_back(Edge(u,v,cap,0));
        edges.push_back(Edge(v,u,0,0));
        m = edges.size();
        G[u].push_back(m-2);
        G[v].push_back(m-1);
    }
    bool bfs(){
        memset(vis,0,sizeof(vis));
        queue<int> q;
        q.push(s);vis[s] = 1,d[s] = 0;
        while(!q.empty()){
            int u = q.front();q.pop();
            for(auto x:G[u]){
                auto e = edges[x];
                if(!vis[e.v] && e.cap > e.flow){
                    vis[e.v] = 1;
                    d[e.v] = d[u] + 1;
                    q.push(e.v);
                }
            }
        }
        return vis[t];
    }
    int dfs(int u,int a){
        if(u == t || a == 0) return a;
        int flow = 0,f,sz = G[u].size();
        for(int &i = cur[u];i < sz;i++){
            auto &e = edges[G[u][i]];
            if(d[u] + 1 == d[e.v] && ((f = dfs(e.v,min(a, e.cap-e.flow)))>0)){
                e.flow += f,edges[G[u][i]^1].flow -= f;
                flow += f,a -= f;
                if(a == 0) break;
            }
        }
        return flow;
    }
    int Maxflow(int s,int t){
        this->s = s,this->t = t;
        int flow = 0;
        while(bfs()){
            memset(cur,0,sizeof(cur));
            flow += dfs(s,inf);
        }
        return flow;
    }
}dic;
int main(){
    int T;
    scanf("%d",&T);
    while(T--){
        int n,m,k,x,y,z;
        scanf("%d%d%d",&n,&m,&k);
        int s = n * m,t = s + 1;
        dic.init(n * m + 2);
        for(int i = 0;i < n;i++){
            dic.add(s,i * m,inf);
            for(int j = 0;j < m - 1;j++){
                scanf("%d",&x);
                dic.add(i * m + j,i * m + j + 1,1000 - x);
            }
            scanf("%d",&x);
            dic.add(i * m + m - 1,t,1000 - x);
        }
        while(k--){
            scanf("%d%d%d",&x,&y,&z);x--,y--;
            for(int j = 1;j <= m;j++){
                if(j - z  > 0){
                    if(j - z > m) dic.add(x * m + j - 1, t, inf);
                    else dic.add(x * m + j - 1, y * m + j - z - 1,inf);
                }
            }
        }
        int cost = dic.Maxflow(s,t);
        if(cost >= inf) cost = -1;
        else cost = n * 1000 - cost;
        printf("%d\n",cost);
    }
    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(网络流)
		
题目给出n,m,k 然后给出n*m的矩阵a[i][j]代表第i个人在获得j 颗糖果能得到的满足值, 然后k是k行每行输入三个整数x,y,z ,x,y,z表示一组限制表示第x个人分到的糖数减去第 ...
 - 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$颗糖获 ...
 - 2017ACM暑期多校联合训练 - Team 5 1001      HDU  6085     Rikka with Candies  (模拟)
		
题目链接 Problem Description As we know, Rikka is poor at math. Yuta is worrying about this situation, s ...
 - HDU 6085 Rikka with Candies(bitset)
		
[题目链接] http://acm.hdu.edu.cn/showproblem.php?pid=6085 [题目大意] 给出一个数组a一个数组b,以及询问数组c, 问对于每个c有多少对a%b=c,答 ...
 - 2017多校第5场 HDU 6085 Rikka with Candies bitset
		
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6085 题意:存在两个长度为n,m的数组A,B.有q个询问,每个询问有一个数字k,可以得到Ai%Bj=k ...
 - HDU 5407——CRB and Candies——————【逆元+是素数次方的数+公式】
		
CRB and Candies Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)T ...
 
随机推荐
- 51nod 1298 圆与三角形——计算几何
			
题目链接:http://www.51nod.com/Challenge/Problem.html#!#problemId=1298 转化成判断三条线段和圆是否
 - js、jquery初始化加载顺序
			
// ready 这个方法只是在页面所有的DOM加载完毕后就会触发 // 方式1 $(function(){ // do something }); // 方式2 $(document).ready( ...
 - Delphi中DLL的创建和使用(转)
			
Delphi中DLL的创建和使用 1.DLL简介: 2.调用DLL: 3.创建DLL: 4.两个技巧: 5.初始化: 6.例外处理. 1.DLL简介 ...
 - 深入理解restfulAPI和 Oauth2.0(精简版)
			
一.restfulAPI 1.解释: restfulAPI协议,我们也可以说是一套API接口编写风格. 它被现在很多企业所认可和默认,是一套成俗的API接口编写方案. 2.restfulAPI之资源 ...
 - python -- sftp的方式下载终端文件
			
可以通过paramiko模块进行远程连接,然后指定文件夹,进行下载. sf = paramiko.Transport((host, port) #创建链接对象,需要终端ip以及sftp使用的端口号 ...
 - [BZOJ2120]数颜色(莫队算法)
			
Description 墨墨购买了一套N支彩色画笔(其中有些颜色可能相同),摆成一排,你需要回答墨墨的提问.墨墨会像你发布如下指令: 1. Q L R代表询问你从第L支画笔到第R支画笔中共有几种不同颜 ...
 - 使用Yeoman自动构建Ember项目
			
Yeoman是什么? Yeoman按照官方说法,它不只是一个工具,还是一个工作流.它其实包括了三个部分yo.grunt.bower,分别用于项目的启动.文件操作.包管理. Yo: Yo是一个项目初始化 ...
 - Python语法之com[1][:-7]
			
strCom = com[0] + ": " + com[1][:-7] 如上应该是一个字符串合成,最后的[1][:-7],我理解是去除com[1]的最后7个字符. 比如com[0 ...
 - 二分查找iOS
			
二分查找(也称折半查找)是很常见的一种在数组中查找数据的算法,作为一名程序员是应该必须会的.它的基础思想:获取数组的中间值,将数组分割成两份,利用查找的值跟中间值进行比较,如果查找的值大于中间值,就在 ...
 - atomic integer 实现
			
public final int getAndAddInt(Object o, long offset, int delta) { int v; do { v = getIntVolatile(o, ...