zoukankan      html  css  js  c++  java
  • 【题解】餐巾计划问题

    【题解】餐巾计划问题

    orz argent

    一定要注意不要调到题目里的坑里来了,要记得脱离实际(大雾)。

    建模方法:我觉得没什么好讲的,真的是灵感问题,此外,这个问题可以直接无源汇上下界网络流。但是我不会

    graph LR 净1 --w=r,c=0--> T 净2 --w=r,c=0--> T 净3 --w=r,c=0--> T 净4 --w=r,c=0--> T S --w=r,c=p--> 净1 S --w=r,c=p--> 净2 S --w=r,c=p--> 净3 S --w=r,c=p--> 净4 脏1--w=r,c=0--> 脏2 脏2--w=r,c=0--> 脏3 脏3--w=r,c=0--> 脏4 S --w=r,c=0--> 脏1 S --w=r,c=0--> 脏2 S --w=r,c=0--> 脏3 S --w=r,c=0--> 脏4 脏1 --w=inf,c=s or m --> 净2 脏1 --w=inf,c=s or m --> 净2

    保证净到(T)一定满流即可。

    //@winlere
    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<queue>
    
    using namespace std;  typedef long long ll;
    inline int qr(){
          register int ret=0,f=0;
          register char c=getchar();
          while(c<48||c>57)f|=c==45,c=getchar();
          while(c>=48&&c<=57) ret=ret*10+c-48,c=getchar();
          return f?-ret:ret;
    }
    
    
    typedef const int& cont;
    const int maxn=4e3+5;
    struct E{
          int to,w,c,nx;
          E(){to=c=w=nx=0;}
          E(cont a,cont b,cont C,cont d){to=a;w=b;c=C;nx=d;}
    }e[maxn<<4|1];
    int head[maxn];
    int cnt=1;
    int T,S;
    const int inf=0x3f3f3f3f;
    queue< int > q;
    inline void add(cont fr,cont to,cont w,cont c,cont f=1){
          e[++cnt]=E(to,w,c,head[fr]);
          head[fr]=cnt;
          if(f)add(to,fr,0,-c,0);
    }
    
    ll d[maxn];
    int fl[maxn];
    int last[maxn];
    int in[maxn];
    int n;
    inline ll mincost(){
          ll ret=0;
          while(1){
    	    for(register int t=1;t<=T;++t) d[t]=1LL<<60,fl[t]=0,in[t]=0;
    	    d[S]=0;q.push(S);fl[S]=inf;
    	    while(q.size()){
    		  register int now=q.front();
    		  q.pop();
    		  in[now]=0;
    		  for(register int t=head[now];t;t=e[t].nx){
    			if(d[e[t].to]>d[now]+e[t].c&&e[t].w>0){
    			      d[e[t].to]=d[now]+e[t].c;
    			      fl[e[t].to]=min(e[t].w,fl[now]);
    			      last[e[t].to]=t;
    			      if(!in[e[t].to]) q.push(e[t].to);
    			      in[e[t].to]=1;
    			}
    		  }
    	    }
    	    if(fl[T]==0)break;
    	    ret+=d[T]*fl[T];
    	    for(register int t=T;t!=S;t=e[last[t]^1].to)
    		  e[last[t]].w-=fl[T],e[last[t]^1].w+=fl[T];
          }
          return ret;
    }
    
    int r[maxn];
    int main(){
                
          n=qr();
          S=n+n+1;T=n+n+2;
          for(register int t=1,t1;t<=n;++t){
    	    add(S,t,r[t]=t1=qr(),0);
    	    add(t+n,T,t1,0);
    	    if(t>1)add(t-1,t,inf,0);
          }
          int p,m,f,N,s;
          p=qr();m=qr();f=qr();N=qr();s=qr();
          for(register int t=1;t<=n;++t){
    	    add(S,t+n,r[t],p);
    	    if(t+m<=n) add(t,t+m+n,inf,f);
    	    if(t+N<=n) add(t,t+N+n,inf,s);
          }
          printf("%lld
    ",mincost());
          return 0;
    }
    
    
  • 相关阅读:
    linux
    day01-02
    测试基础
    cookie session
    多表表与表关系 增删改查 admin
    连接数据库 创建表 字段和参数 增删改查
    LeetCode OJ:Triangle(三角形)
    LeetCode OJ:Unique Paths II(唯一路径II)
    LeetCode OJ:Unique Paths(唯一路径)
    使用双栈实现一个队列
  • 原文地址:https://www.cnblogs.com/winlere/p/11241214.html
Copyright © 2011-2022 走看看