zoukankan      html  css  js  c++  java
  • 【网络流24题10】餐巾计划问题

    题面戳我
    题面描述
    一个餐厅在相继的N天里,第i天需要Ri块餐巾(i=l,2,…,N)。餐厅可以从三种途径获得餐巾。
    (1)购买新的餐巾,每块需p分;
    (2)把用过的餐巾送到快洗部,洗一块需m天,费用需f分(f<p)。如m=l时,第一天送到快洗部的餐巾第二天就可以使用了,送慢洗的情况也如此。
    (3)把餐巾送到慢洗部,洗一块需n天(n>m),费用需s分(s<f)。
    在每天结束时,餐厅必须决定多少块用过的餐巾送到快洗部,多少块送慢洗部。在每天开始时,餐厅必须决定是否购买新餐巾及多少,使洗好的和新购的餐巾之和满足当天的需求量Ri,并使N天总的费用最小
    输入输出格式
    输入格式:
    输入文件共3行,第1行为总天数;第2行为每天所需的餐巾块数;第3行为每块餐巾的新购费用p,快洗所需天数m,快洗所需费用f,慢洗所需天数n,慢洗所需费用s。
    输出格式:
    输出文件共1行为最小的费用。
    输入输出样例
    输入样例#1:

    3
    3 2 4
    10 1 6 2 3
    

    输出样例#1:

    64
    

    说明
    N<=2000
    ri<=10000000
    p,f,s<=10000
    时限4s

    sol

    网络流24题里面很有意思的一个建图
    因为每天最终的ri是固定的,所以我们可以直接假设每天都有ri块旧餐巾。
    每天拆成两个点,新建源点汇点(S),(T)
    (S)连向(i')(i)连向(T),均容量(R_i)费用0;
    (S)连向(1)容量(inf)费用(p),其余(i-1)连向(i)容量(inf)费用0;对应购买餐巾(可以当做是第一天买了所有餐巾,然后餐巾可以留到以后去使用)
    (i')分别连向(i+m)(i+n(i+m,i+n<=N)),容量(inf)费用对应(f)(s)。(快洗或慢洗)
    建完图跑费用流。

    code

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<queue>
    using namespace std;
    #define inf 1000000000
    const int _ = 100005;
    struct edge{int to,next,w,cost;}a[_<<1];
    int N,R[_],p,m,f,n,s,S,T,head[_],cnt=1,dis[_],vis[_],pe[_],pv[_];
    long long ans;
    queue<int>Q;
    int gi()
    {
    	int x=0,w=1;char ch=getchar();
    	while ((ch<'0'||ch>'9')&&ch!='-') ch=getchar();
    	if (ch=='-') w=0,ch=getchar();
    	while (ch>='0'&&ch<='9') x=(x<<3)+(x<<1)+ch-'0',ch=getchar();
    	return w?x:-x;
    }
    void link(int u,int v,int w,int cost)
    {
    	a[++cnt]=(edge){v,head[u],w,cost};
    	head[u]=cnt;
    	a[++cnt]=(edge){u,head[v],0,-cost};
    	head[v]=cnt;
    }
    bool spfa()
    {
    	memset(dis,63,sizeof(dis));
    	dis[S]=0;Q.push(S);
    	while (!Q.empty())
    	{
    		int u=Q.front();Q.pop();
    		for (int e=head[u];e;e=a[e].next)
    		{
    			int v=a[e].to;
    			if (a[e].w&&dis[v]>dis[u]+a[e].cost)
    			{
    				dis[v]=dis[u]+a[e].cost;
    				pe[v]=e;pv[v]=u;
    				if (!vis[v]) vis[v]=1,Q.push(v);
    			}
    		}
    		vis[u]=0;
    	}
    	return dis[T]<dis[0];
    }
    int main()
    {
    	N=gi();S=N*2+1;T=S+1;
    	for (int i=1;i<=N;i++)
    		R[i]=gi();
    	p=gi();m=gi();f=gi();n=gi();s=gi();
    	for (int i=1;i<=N;i++)
    	{
    		link(i,T,R[i],0),link(S,i+N,R[i],0);
    		if (i==1) link(S,i,inf,p);
    		else link(i-1,i,inf,0);
    		if (i+m<=N) link(i+N,i+m,inf,f);
    		if (i+n<=N) link(i+N,i+n,inf,s);
    	}
    	while (spfa())
    	{
    		int sum=inf;
    		for (int i=T;i!=S;i=pv[i])
    			sum=min(sum,a[pe[i]].w);
    		for (int i=T;i!=S;i=pv[i])
    			a[pe[i]].w-=sum,a[pe[i]^1].w+=sum,ans+=1ll*sum*a[pe[i]].cost;
    	}
    	printf("%lld
    ",ans);
    	return 0;
    }
    
    
  • 相关阅读:
    PHP运行出现Notice : Use of undefined constant 的解决办法
    Winfrom 设置Panel添加滚动条
    Unable to find the wrapper ”https”
    winfrom 控件的显示隐藏方法
    winfrom 窗体控件实现二级联动
    【最小生成树】Bzoj1601[Usaco2008 Oct]灌水
    【强连通分量】Bzoj1051 HAOI2006 受欢迎的牛
    【Homework】LCA&RMQ
    【建图+最短路】Bzoj1001 狼抓兔子
    【组合数学】Bzoj2916 [Poi1997]Monochromatic Triangles
  • 原文地址:https://www.cnblogs.com/zhoushuyu/p/8185206.html
Copyright © 2011-2022 走看看