zoukankan      html  css  js  c++  java
  • ZOJ3229 有源汇上下界最大流

    http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3229

    题意:报社给M个妹子拍照,并且拍照N天,每一天给给定的C个妹子拍照,每天拍照数量不能超过D张,并且给每个妹子拍照的数量有限制(l,r),所有妹子n天总共拍的照片不能小于Gi张,求最多可以拍多少张照以及拍照方案

    题意里这么多限制条件,考虑建图用上下界网络流做。

    模型:设置一个起点对每一天连一条[0,D]的边,每一天向对应的被拍照的妹子连一条(l,r)的边,然后设置一个终点,将每个妹子向终点连一条(G,INF)的边

    当然建图不是这么建,在上述模型上用有源汇的最大流就可以了

    #include <map>
    #include <set>
    #include <ctime>
    #include <cmath>
    #include <queue>
    #include <stack>
    #include <vector>
    #include <string>
    #include <cstdio>
    #include <cstdlib>
    #include <cstring>
    #include <sstream>
    #include <iostream>
    #include <algorithm>
    #include <functional>
    using namespace std;
    #define For(i, x, y) for(int i=x;i<=y;i++)  
    #define _For(i, x, y) for(int i=x;i>=y;i--)
    #define Mem(f, x) memset(f,x,sizeof(f))  
    #define Sca(x) scanf("%d", &x)
    #define Sca2(x,y) scanf("%d%d",&x,&y)
    #define Sca3(x,y,z) scanf("%d%d%d",&x,&y,&z)
    #define Scl(x) scanf("%lld",&x);  
    #define Pri(x) printf("%d
    ", x)
    #define Prl(x) printf("%lld
    ",x);  
    #define CLR(u) for(int i=0;i<=N;i++)u[i].clear();
    #define LL long long
    #define ULL unsigned long long  
    #define mp make_pair
    #define PII pair<int,int>
    #define PIL pair<int,long long>
    #define PLL pair<long long,long long>
    #define pb push_back
    #define fi first
    #define se second 
    typedef vector<int> VI;
    int read(){int x = 0,f = 1;char c = getchar();while (c<'0' || c>'9'){if (c == '-') f = -1;c = getchar();}
    while (c >= '0'&&c <= '9'){x = x * 10 + c - '0';c = getchar();}return x*f;}
    const double eps = 1e-9;
    const int maxn = 5010;
    const int maxm = 5e5 + 10;
    const int INF = 0x3f3f3f3f;
    const int mod = 1e9 + 7; 
    int N,M,K;
    int a[maxn],F[maxm];
    struct dinic{
        struct Edge{
            int to,next,cap,flow,id;
            Edge(){}
            Edge(int to,int next,int cap,int flow,int id):
                to(to),next(next),cap(cap),flow(flow),id(id){}
        }edge[maxm * 2];
        int head[maxn],tot,cur[maxn],s,t,n,dep[maxn];
        void init(int n){
            this->n = n;
            for(int i = 0 ; i <= n ; i ++) head[i] = -1;
            tot = 0;
        }
        void add(int u,int v,int w,int id){
            edge[tot] = Edge(v,head[u],w,0,id);
            head[u] = tot++;
            edge[tot] = Edge(u,head[v],0,0,id);
            head[v] = tot++;
        }
        inline bool bfs(){
            for(int i = 0 ; i <= n ; i ++) dep[i] = -1;
            dep[s] = 1;
            queue<int>Q; Q.push(s);
            while(!Q.empty()){
                int u = Q.front(); Q.pop();
                for(int i = head[u]; ~i ; i = edge[i].next){
                    int v = edge[i].to;
                    if(~dep[v] || edge[i].flow >= edge[i].cap) continue;
                    dep[v] = dep[u] + 1;
                    Q.push(v);
                }
            }
            return ~dep[t];
        }
        inline int dfs(const int &u,int a){
            if(u == t || !a) return a;
            int flow = 0;
            for(int &i = cur[u];~i ; i = edge[i].next){
                int v = edge[i].to;
                if(dep[v] != dep[u] + 1) continue;
                int f = dfs(v,min(a,edge[i].cap - edge[i].flow));
                flow += f; a -= f;
                edge[i].flow += f;
                edge[i ^ 1].flow -= f;
                //cout << a<< endl;
                if(!a)    return flow;    
            }
            return flow;
        }
        int maxflow(int s,int t){
            this->s = s; this->t = t;
            int flow = 0;
            while(bfs()){
                for(int i = 0 ;i <= n ; i ++) cur[i] = head[i];
                flow += dfs(s,INF);
            }
            return flow;
        }
        void solve(){
            for(int i = 0; i <= n ; i ++){
                for(int j = head[i]; ~j ; j = edge[j].next){
                    int v = edge[j].to;
                    if(edge[j].flow > 0) F[edge[j].id] = edge[j].flow;
                }
            }
        }
        void del(int S,int T,int SS,int TT){
            for(int i = head[T]; ~i; i = edge[i].next){
                if(edge[i].cap == INF){
                    edge[i].cap = edge[i].flow = 0;
                    edge[i ^ 1].cap = edge[i ^ 1].flow = 0;
                    break;
                }
            }
            for(int i = head[SS]; ~i; i = edge[i].next){
                edge[i].cap = edge[i].flow = 0;
                edge[i ^ 1].cap = edge[i ^ 1].flow = 0;
            }
            for(int i = head[TT]; ~i; i = edge[i].next){
                edge[i].cap = edge[i].flow = 0;
                edge[i ^ 1].cap = edge[i ^ 1].flow = 0;
            }
        }
    }g;
    int e[maxm];
    int main(){
        while(~Sca2(N,M)){
            for(int i = 0; i <= N + M + 4; i ++)a[i] = 0;
            int s = M + N + 1,t = N + M + 2;
            int SS = N + M + 3,TT = N + M + 4;
            g.init(N + M + 4);
            for(int i = 1; i <= M ; i ++){
                int G; Sca(G);
                g.add(N + i,t,INF - G,0);
                a[t] -= G; a[N + i] += G;
            }
            int cnt = 0;
            for(int i = 1; i <= N ; i ++){
                int c,d; Sca2(c,d);
                g.add(s,i,d,0);
                for(int j = 1; j <= c; j ++){
                    int id,l,r; Sca3(id,l,r);
                    id = id + 1 + N;
                    g.add(i,id,r - l,++cnt);
                    e[cnt] = l;
                    a[id] -= l; a[i] += l;
                }
            }
            for(int i = 0 ; i <= cnt + 1; i ++) F[i] = 0;
            g.add(t,s,INF,cnt + 1);
            int sum = 0;
            for(int i = 1; i <= N + M + 2; i ++){
                if(a[i] > 0){
                    g.add(i,TT,a[i],0);
                    sum += a[i];
                }else if(a[i] < 0){
                    g.add(SS,i,-a[i],0);
                }
            }
            if(sum != g.maxflow(SS,TT)){
                puts("-1");
            }else{
                g.solve();
                g.del(s,t,SS,TT);
                int ans = g.maxflow(s,t) + F[cnt + 1];
                Pri(ans);
                g.solve();
                for(int i = 1; i <= cnt; i ++){
                    Pri(F[i] + e[i]);
                }
            } 
            puts("");
        } 
        return 0;
    }
  • 相关阅读:
    《软件需求十步走》阅读笔记一
    专业实训项目需求分析
    2015秋季学期个人阅读计划
    最后期限阅读笔记3
    最后期限阅读笔记2
    最后期限阅读笔记1
    你的灯亮着么阅读笔记3
    DPDK(二):准备知识7---linux虚拟网络设备
    DPDK(二)准备6---PMD
    DPDK(二):准备知识4 --- 无锁FIFO环形队列
  • 原文地址:https://www.cnblogs.com/Hugh-Locke/p/11146502.html
Copyright © 2011-2022 走看看