• 【BZOJ3280】 小R的烦恼(费用流,建模)


    有很浓厚的熟悉感?餐巾计划问题?
    不就是多了几个医院,相当于快洗部和慢洗部开了分店.

    考虑建图:

    如果把每一天拆成两个点,一个表示需求,另一个表示拥有的话.

    显然就是一个两边的图,考虑如果我现在有人,但是可以不用,显然可以向后面一天传递.

    如果我死了人,要救活,显然是需求向拥有连边.

    然后就差不多了.直接跑费用流就好了.

    #include<stdio.h>
    #include<stdlib.h>
    #include<string.h>
    #include<math.h>
    #include<algorithm>
    #include<queue>
    #include<set>
    #include<map>
    #include<iostream>
    using namespace std;
    #define ll long long
    #define re register
    #define file(a) freopen(a".in","r",stdin);freopen(a".out","w",stdout)
    inline int gi()
    {
        int f=1,sum=0;char ch=getchar();
        while(ch>'9' || ch<'0'){if(ch=='-')f=-1;ch=getchar();}
        while(ch>='0' && ch<='9'){sum=(sum<<3)+(sum<<1)+ch-'0';ch=getchar();}
        return f*sum;
    }
    typedef pair<int,int> pii;
    const int N=50,Inf=1e9+10;
    int front[N<<2],nxt[N*N<<2],to[N*N<<2],w[N*N<<2],c[N*N<<2],cnt,s,t,fa[N<<2],pre[N<<2],dis[N<<3],vis[N<<2],n,m,k,need;
    queue<int>Q;
    void Add(int u,int v,int val,int f){
        to[cnt]=v;nxt[cnt]=front[u];front[u]=cnt;w[cnt]=val;c[cnt++]=f;
        to[cnt]=u;nxt[cnt]=front[v];front[v]=cnt;w[cnt]=0;c[cnt++]=-f;
    }
    bool SPFA(){
        for(int i=0;i<=t;i++)dis[i]=Inf;
        dis[s]=0;Q.push(0);
        while(!Q.empty()){
            int u=Q.front();Q.pop();vis[u]=0;
            for(int i=front[u];i!=-1;i=nxt[i]){
                int v=to[i];
                if(w[i] && dis[v]>dis[u]+c[i]){
                    dis[v]=dis[u]+c[i];fa[v]=u;pre[v]=i;
                    if(!vis[v]){
                        vis[v]=1;Q.push(v);
                    }
                }
            }
        }
        return dis[t]!=Inf;
    }
    pii McMf(){
        pair<int,int>ans;
        while(SPFA()){
            int di=Inf;
            for(int i=t;i!=s;i=fa[i])di=min(di,w[pre[i]]);
            ans.first+=di;ans.second+=di*dis[t];
            for(int i=t;i!=s;i=fa[i]){w[pre[i]]-=di;w[pre[i]^1]+=di;}
        }
        return ans;
    }
    int main()
    {
        int T=gi(),Case=0;
        while(T--){Case++;printf("Case %d: ",Case);
            n=gi();s=0;t=n+n+1;
            m=gi();k=gi();need=0;
            memset(front,-1,sizeof(front));cnt=0;
            for(int i=1;i<=n;i++){
                int x=gi();need+=x;
                Add(s,i,x,0);Add(i+n,t,x,0);
            }
            for(int i=1;i<=m;i++){
                int x=gi(),y=gi();
                Add(s,n+1,x,y);
            }
            for(int i=1;i<=k;i++){
                int x=gi(),y=gi();
                for(int j=1;j<=n-x-1;j++)
                    Add(j,j+x+n+1,Inf,y);
            }
            for(int i=1;i<n;i++)Add(i+n,i+n+1,Inf,0);
            pair<int,int>ans=McMf();
            if(ans.first<need)puts("impossible");
            else printf("%d
    ",ans.second);
        }
        return 0;
    }
    
  • 相关阅读:
    [例程]string.trim().length()的用法
    用各种look and feel打造swing界面
    深入浅出Java多线程(1)方法 join
    eclipse中cvs使用配置
    什么时候用Vector, 什么时候改用ArrayList?
    array,vertor,arraylist,hashable,hashmap等几个易混淆概念的区别
    java.lang.Class.getResource()这哥个方法主要是做什么用
    织梦dedecms实现按照字母搜索的实现方法
    浅析JTable与TableModel、TableCellRenderer、TableCellEditor接口——使用JComboBox显示单元格的值
    用java –jar 命令运行Jar包
  • 原文地址:https://www.cnblogs.com/mleautomaton/p/10303066.html
Copyright © 2020-2023  润新知