• luogu P1251 餐巾计划问题


    题目链接

    luogu P1251 餐巾计划问题

    题解

    考虑上下界网络流
    对于没个时间点拆成两个点(A,A')
    由S点连向(A)限制最小流入量,处理这部分流量时相当于计算花费
    然后就是考虑如和相依状态转移,建边
    不要忘了剩下干净的

    代码

    // luogu-judger-enable-o2
    #include<queue>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    using std::queue;
    using std::min;
    #define INF 0x7fffffff
    const int maxn = 770000;
    inline int read() {
        int x=0;char c=getchar();
        while(c<'0'||c>'9') c=getchar();
        while(c<='9'&&c>='0') x=x*10+c-'0',c=getchar();
        return x;
    }
    int N,S,T,ned[maxn],p,m,f,n,s;
    struct node{
        int u,v,flow,next,cost;
    }edge[maxn];int head[maxn],num=1;
    inline void add_edge(int u,int v,int flow,int cost) {
        edge[++num].v=v;edge[num].u=u,edge[num].flow=flow,edge[num].next=head[u];head[u]=num;
        edge[num].cost=cost;
        edge[++num].v=u;edge[num].u=v,edge[num].flow=0;edge[num].next=head[v];head[v]=num;
        edge[num].cost=-cost;
    }
    int Min_cost=0;
    int pre[maxn],dis[maxn];
    bool vis[maxn];
    bool spfa() {
        memset(dis,0x3f,sizeof dis);
        memset(vis,0,sizeof vis);
        queue<int>que;
        que.push(S),vis[S]=1;dis[S]=0;
        while(!que.empty()) {
            int u=que.front();que.pop();
            for(int i=head[u];i;i=edge[i].next) {
                int v=edge[i].v;
                if(edge[i].flow && dis[v]>dis[u]+edge[i].cost) {
                    dis[v]=dis[u]+edge[i].cost;
                    pre[v]=i;
                    if(!vis[v]) que.push(v),vis[v]=1;
                }
            }
            vis[u]=0;
        }
        if(dis[T]!=0x3f3f3f3f)return true;
        else return false;
    }
    int calc() {
        int ret=0,maxx=0x3f3f3f3f;
        for(int i=T;i!=S;i=edge[pre[i]].u) 
            maxx=min(edge[pre[i]].flow,maxx);
        for(int i=T;i!=S;i=edge[pre[i]].u) {
            edge[pre[i]].flow-=maxx;
            edge[pre[i]^1].flow+=maxx;
            ret+=maxx*edge[pre[i]].cost;
        }
        return ret;
    }
    long long ans=0;
    void mcmf() {
        while(spfa()) 
            ans+=calc();
    }
    int main() {
        N=read();
        for(int i=1;i<=N;++i) ned[i]=read();
        p=read(),m=read(),f=read(),n=read(),s=read();
        T=N*2+1;
        for(int i=1;i<=N;++i) {
            add_edge(S,i,ned[i],0);
            add_edge(N+i,T,ned[i],0);
        }
        for(int i=1;i<=N;++i) {
            if(i+1<=N)add_edge(i,i+1,INF,0);
            if(i+m<=N)add_edge(i,N+i+m,INF,f);
            if(i+n<=N)add_edge(i,N+i+n,INF,s);
            add_edge(S,i+N,INF,p);
        }
        mcmf();
        printf("%lld
    ",ans);
        return 0;
    }	
    
  • 相关阅读:
    『在线工具』 基于 xsser.me 源码 + BootStrap 前端 的 XSS 平台
    『Python』Python 调用 ZoomEye API 批量获取目标网站IP
    『Python』 多线程 共享变量的实现
    『Python』 多线程 端口扫描器
    打印机PCL漏洞原理分析
    『GitHub』Git常用命令记录
    『Python』爬行搜索引擎结果获得指定主机二级域名及IP信息
    iOS使用Runtime给分类动态绑定属性
    Swift介绍(基于Swift4版本)
    iOS中的block模板
  • 原文地址:https://www.cnblogs.com/sssy/p/8429977.html
Copyright © 2020-2023  润新知