superoj441 餐巾計劃

題目描述

輸入格式

輸入文件第 1 行有 6 個正整數 N,p,m,f,n,s。其中 N 是要安排餐巾使用計劃的天數;p 是每塊新餐巾的費用;m 是快洗部洗一塊餐巾需用天數;f 是快洗部洗一塊餐巾需要的費用;n 是慢洗部洗一塊餐巾需用天數;s 是慢洗部洗一塊餐巾需要的費用。數據範圍如下:1≤N≤800,1≤p≤50,1≤m≤20, 1≤f≤20,1≤n≤20,1≤s≤10。
接下來的 N 行是餐廳在相繼的 N 天裏,每天需用的餐巾數(每個數不超過500)。

輸出格式

輸出餐廳在相繼的 N 天裏使用餐巾的最小總花費。

樣例數據 1

輸入  [複製]

3 10 2 3 3 2 


7

輸出

145

費用流

用類似於可重複揹包刪邊

注意這坑題慢洗可能比快洗要快(坑哭我)

#include<cmath>
#include<ctime>
#include<cstdio>
#include<cstdlib>
#include<string>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<queue>
#include<vector>

using namespace std;
struct node
{
   int to;
   int next;
   int liu;
   int cost;
   int from;
};
node bian[1300000];
int first[40010];
int dis[40010];
int xuqiu[40010]; 
int n,p,m,f,z,s;  //p新餐巾費用 m快洗time f快洗費用 z慢洗time s慢洗費用  
int size;
queue <int> q;
bool exsit[40000];
int zcost,zflow;
int pre[40000];

void inser(int a,int b,int liu,int cost)
{
	size++;
	bian[size].to=b;
	bian[size].next=first[a];
	first[a]=size;
	bian[size].liu=liu;
    bian[size].from=a;
    bian[size].cost=cost;
}

void init()
{
	int i,j;
    scanf("%d%d%d%d%d%d",&n,&p,&m,&f,&z,&s);
	for(i=1;i<=n;i++)
      {
         scanf("%d",&xuqiu[i]);	  
	  }
    for(i=1;i<=n;i++)
     {
     	inser(0,i,xuqiu[i],0);
     	inser(i,0,0,0);
     	
	 }
    for(i=1;i<=n;i++)
      {
      	inser(n+i,2*n+1,xuqiu[i],0);
      	inser(2*n+1,n+i,0,0);
	  }
    
    for(i=1;i<n;i++)
      {
      	inser(i,i+1,10000000,0);
      	inser(i+1,i,0,0);
	  }
    
    
 
    for(i=1;i<=n;i++)
      {  
        if(i+m<=n)
        {
		inser(i,i+n+m,10000000,f);
        inser(i+n+m,i,0,-f);
        }
        if(i+z<=n)
        {
		inser(i,i+n+z,10000000,s);
        inser(i+n+z,i,0,-s);
        }
		inser(0,n+i,10000000,p);
		inser(n+i,0,0,-p);  
	  }
    inser(4*n,0,100000000,0);
}

bool spfa()
{
	while(!q.empty()) q.pop();
    memset(dis,127,sizeof(dis));
    memset(exsit,false,sizeof(exsit));
    memset(pre,-1,sizeof(pre));
    pre[0]=size;   
	dis[0]=0;   	
	exsit[0]=true;
	q.push(0);
	
	while(!q.empty())
	  {
	  	 int u=q.front();
	  	 q.pop();
	  	 exsit[u]=false;
	  	 for(int i=first[u];i!=0;i=bian[i].next)
	  	   {
	  	   	   int d=bian[i].to;
	  	   	   if(bian[i].liu!=0&&dis[d]>dis[u]+bian[i].cost)
	  	   	      {
	  	   	         dis[d]=dis[u]+bian[i].cost;
				     pre[d]=i;		  					 
					 if(!exsit[d]) 
					   {
					   	  exsit[d]=true;
					   	 // if(exsit[n*2+1]) return true;
					   	  q.push(d);
					   }	  	 
				  }
		   }
	  }
    if(dis[2*n+1]>1000000000) return false;
	return true;
}




int flow_()
{
    int flow;
	while(spfa())
      {
      	flow=0x7fffffff;
      	for(int i=pre[2*n+1];bian[i].from!=4*n;i=pre[bian[i].from])
      	  {
      	  	 if(bian[i].liu<flow) flow=bian[i].liu;
		  }
      	for(int i=pre[2*n+1];bian[i].from!=4*n;i=pre[bian[i].from])
      	  {
      	  	  bian[i].liu-=flow;
      	  	  bian[i+1].liu+=flow;
		      zcost+=flow*bian[i].cost;   
		  }	    
	    zflow+=flow; 
	  }
	
	 return zcost; 
}

int main()
{
  // freopen("lx.in","r",stdin);
 //  freopen("lx.out","w",stdout);
   int i,j,k;
   
   init();
   int ans=flow_();
   cout<<ans;
   //cout<<zflow<<" ";
  // cout<<size;
   return 0;
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章