zoukankan      html  css  js  c++  java
  • HDU 6126 Give out candies 最小割

    Give out candies

    Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 524288/524288 K (Java/Others)

    Problem Description
    There are n children numbered 1 to n, and HazelFan's task is to give out candies to the children. Each children must be given at least 1 and at most m candies. The children raised k pieces of requirements, and every piece includes three integers x,y,z, means that the number of candies given to the child numbered x, subtract the number of candies given to the child number y, the result should not be more than z. Besides, if the child numbered i is given j candies, he or she will get wi,jsatisfaction score, now you need to help HazelFan maximize the sum of the satisfaction scores of these children.
     
    Input
    The first line contains a positive integer T(1T5), denoting the number of test cases.
    For each test case:
    The first line contain three positive integers n,m,k(1n,m50,1k150).
    The next n lines, the ith line contains m positive integers, the jth integer denotes wi,j.
    The next k lines, each line contains three integers x,y,z(1x,yn,z∣<233), denoting a piece of requirement.
     
    Output
    For each test case:
    A single line contains a nonnegative integer, denoting the answer. Particularly, if there is no way to give out candies, print -1.
     
    Sample Input
    2 2 1 1 1 1 1 2 1 3 3 2 1 2 3 2 3 1 3 1 2 1 2 0 2 3 0
     
    Sample Output
    2 7
     
     
    题意:
      有n个人,每个人i获得j个糖果会有一个满意度wij,现在有一些约数条件xi,yi,zi,即xi获得的糖果数量-yi获得的糖果数量不超过zi,求最大满意度。
    题解:
      用i.j这点表示给第i个孩子至少j块糖
      当这个点属于S集合时所代表条件成立。
      然后i.j->i.j+1连1000-wi,j,i.m向T连1000-wi,m,S向i.1连inf。
      如果存在ax-ay>=z,x.k->y.k+z连inf。跑最小割,再用n*1000减掉答案。
    #include<bits/stdc++.h>
    using namespace std;
    #define ls i<<1
    #define rs ls | 1
    #define mid ((ll+rr)>>1)
    #define pii pair<int,int>
    #define MP make_pair
    typedef long long LL;
    typedef unsigned long long ULL;
    const long long INF = 1e18+1LL;
    const double pi = acos(-1.0);
    const int N = 1e5+10, M = 1e3+20,inf = 1000000;
    
    int head[N],t=2,h[N],q[N],S,T,ans = 0,huyou[N];
    struct edge{int to,next,v;}e[N * 2];
    void adds(int u,int v,int w)
     {e[t].to=v;e[t].v=w;e[t].next=head[u];head[u]=t++;}
    void add(int u,int v,int w) {adds(u,v,w);adds(v,u,0);}
    
    inline int bfs() {
        for(int i = 0; i <= 5000; ++i) h[i] = -1;
        int l=0,r=1,now;
        q[l]=S;
        h[S]=0;
        while(l!=r){
            now=q[l++];//if(l == 100000) l=0;
            for(int i=head[now];i!=-1;i=e[i].next) {
                if(e[i].v&&h[e[i].to]==-1) {
                    h[e[i].to]=h[now]+1;
                    q[r++]=e[i].to;
                   // if(r==100000) r = 0;
                }
            }
        }
        if(h[T]==-1) return 0;
        else return 1;
    }
    
    inline int dfs(int x,int f) {
            if(x == T || f == 0) return f;
            int used=0,w;
            for(int &i=huyou[x]; i!=-1;i=e[i].next) {
                if(e[i].v&&h[e[i].to] == h[x] + 1) {
                    w=dfs(e[i].to,min(f-used,e[i].v));
                    used+=w;e[i].v-=w;e[i^1].v+=w;
                    f-=w;
                    if(f == 0) break;
                }
            }
            return used;
    }
    void dinic() {
        while(bfs()) {
            memcpy(huyou,head,sizeof(huyou));
            ans+=dfs(S,inf);
        }
    }
    
    int n,m,k,a[56][56];
    int main() {
        int TT;
        scanf("%d",&TT);
        while(TT--) {
            scanf("%d%d%d",&n,&m,&k);
             S = 0,T = n*m+1;
             t = 2;
             for(int i = 0; i <= 50000; ++i) head[i] = -1;
            for(int i = 1; i <= n; ++i) {
                for(int j = 1; j <= m; ++j) scanf("%d",&a[i][j]);
    
                add(S,(i-1)*m+1,1000000);
                for(int j = 1; j < m; ++j)
                    add((i-1)*m+j,(i-1)*m+j+1,10000-a[i][j]);
                add(i*m,T,10000-a[i][m]);
            }
    
            for(int i = 1; i <= k; ++i) {
                int x,y,z,last = 0;
                scanf("%d%d%d",&x,&y,&z);
                for(int j = max(z+1,1); j <= m && j-z <= m; ++j) {
                    add((x-1)*m+j,(y-1)*m+j-z,1000000);
                    last = j;
                }
                if(last + 1 - z > m && last+1<=m)
                    add((x-1)*m + last+1,T,1000000);
            }
            ans = 0;
            dinic();
            if(ans >= 1000000) puts("-1");
            else
            printf("%d
    ",n*10000 - ans);
        }
        return 0;
    }
  • 相关阅读:
    基于深度学习的单目图像深度估计
    OpenCV探索之路(二十三):特征检测和特征匹配方法汇总
    TensorFlow练习24: GANs-生成对抗网络 (生成明星脸)
    深度估计&平面检测小结
    论文翻译——Rapid 2D-to-3D conversion——快速2D到3D转换
    Opencv改变图像亮度和对比度以及优化
    如何将OpenCV中的Mat类绑定为OpenGL中的纹理
    Eclipse控制台中文乱码
    给java中的System.getProperty添加新的key value对
    中文简体windows CMD显示中文乱码解决方案
  • 原文地址:https://www.cnblogs.com/zxhl/p/7388713.html
Copyright © 2011-2022 走看看