zoukankan      html  css  js  c++  java
  • 【Luogu】P1251餐巾计划(上下界费用流)

      题目链接

      学了一下上下界费用流,似乎很nb。但是我说得不好,所以这里给出博客链接。

      某dalao的博客

      然后这道题的解法就是先用上下界费用流的建图方式连早上和晚上之间的那条边,保证当天一定会有r条或以上的餐巾可用。

      然后考虑买,快洗,慢洗和放起来的诸多情况。

      

    #include<cstdio>
    #include<cstdlib>
    #include<cstring>
    #include<algorithm>
    #include<cctype>
    #include<queue>
    #define maxn 5030
    using namespace std;
    inline long long read(){
        long long num=0,f=1;
        char ch=getchar();
        while(!isdigit(ch)){
            if(ch=='-')    f=-1;
            ch=getchar();
        }
        while(isdigit(ch)){
            num=num*10+ch-'0';
            ch=getchar();
        }
        return num*f;
    }
    
    struct Edge{
        int from,next,to,val,dis;
    }edge[maxn*20];
    int head[maxn],num;
    inline void addedge(int from,int to,int val,int dis){
        edge[++num]=(Edge){from,head[from],to,val,dis};
        head[from]=num;
    }
    inline void add(int from,int to,int val,int dis){
        addedge(from,to,val,dis);
        addedge(to,from,0,-dis);
    }
    
    inline int count(int i){    return i&1?i+1:i-1;    }
    
    int dis[maxn];
    int pre[maxn];
    bool vis[maxn];
    int flow[maxn];
    int Start,End;
    
    int spfa(){
        memset(dis,127/3,sizeof(dis));    int pinf=dis[0];
        dis[Start]=0;    flow[Start]=0x7fffffff;
        queue<int>q; q.push(Start);
        while(!q.empty()){
            int from=q.front();    q.pop();    vis[from]=0;
            for(int i=head[from];i;i=edge[i].next){
                int to=edge[i].to;
                if(edge[i].val==0||dis[to]<=dis[from]+edge[i].dis)    continue;
                dis[to]=dis[from]+edge[i].dis;
                pre[to]=i;    flow[to]=min(flow[from],edge[i].val);
                if(vis[to])    continue;
                vis[to]=1;    q.push(to);
            }
        }
        if(dis[End]==pinf)    return 0;
        int now=End;
        while(now!=Start){
            int ret=pre[now];
            edge[ret].val-=flow[End];    edge[count(ret)].val+=flow[End];
            now=edge[ret].from;
        }
        return (long long)dis[End]*flow[End];
    }
    
    int r[maxn];
    
    int main(){
        int N=read();    End=N*2+1;
        for(int i=1;i<=N;++i){
            r[i]=read();
            add(Start,i+N,r[i],0);
            add(i,End,r[i],0);
            add(i,i+N,0x7fffffff,0);
        }
        int p=read(),m=read(),f=read(),n=read(),s=read();
        for(int i=1;i<=N;++i){
            add(Start,i,0x7fffffff,p);
            if(i!=N)    add(i,i+1,0x7fffffff,0);
            if(i+m>N)    continue;
            add(i+N,i+m,0x7fffffff,f);
            if(i+n>N)    continue;
            add(i+N,i+n,0x7fffffff,s);
            
        }
        long long ans=0;
        while(1){
            long long now=spfa();
            if(now==0)    break;
            ans+=now;
        }
        printf("%lld
    ",ans);
        return 0;
    }

    https://www.luogu.org/problemnew/show/P1251

  • 相关阅读:
    mongodb数据库shell
    PLINK pca
    xgboost 安装
    tensorflow之损失函数
    php,mysql存储过程的简单例子
    ECharts初体验
    mysql常用连接查询
    php流程控制
    php循环
    高效率php注意事项
  • 原文地址:https://www.cnblogs.com/cellular-automaton/p/8448905.html
Copyright © 2011-2022 走看看