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

    网络流24题 餐巾纸计划

    此题费用流很明显,但其难度在于建模。
    首先说一下建模方式

    • 先将每个点拆成两个,Xi和Yi
    • 1.从源点向每个Xi连条流量为ri,0费用的边
    • 2.从每个Yi向汇点连条流量为ri,0费用的边
    • 3.从每个Xi向Xi+1连条流量无限,0费用的边
    • 4.从每个Xi向Yi+m连流量无限,费用为f的边
    • 5.从每个Xi向Yi+n连流量无限,费用为s的边
    分析建模
    • 首先你要明白每个Xi表示当天用完的餐巾的数量,Yi代表每天拥有的可用餐巾的数量,所以他们的数量显然是ri,所以有1,2连边。
    • 对于每天用完的餐巾,我们可以留到下一天处理,所以有3。
    • 还可以送到快洗部和慢洗部,所以有4,5。
    代码
    #include<bits/stdc++.h>
    using namespace std;
    typedef int sign;
    typedef long long ll;
    #define For(i,a,b) for(register sign i=(sign)a;i<=(sign)b;++i)
    #define Fordown(i,a,b) for(register sign i=(sign)a;i>=(sign)b;--i)
    const int N=4000+5;
    bool cmax(sign &a,sign b){return (a<b)?a=b,1:0;}
    bool cmin(sign &a,sign b){return (a>b)?a=b,1:0;}
    template<typename T>T read()
    {
    	T ans=0,f=1;
    	char ch=getchar();
    	while(!isdigit(ch)&&ch!='-')ch=getchar();
    	if(ch=='-')f=-1,ch=getchar();
    	while(isdigit(ch))ans=(ans<<3)+(ans<<1)+(ch-'0'),ch=getchar();
    	return ans*f;
    }
    void file()
    {
    	#ifndef ONLINE_JUDGE
    		freopen("1251.in","r",stdin);
    		freopen("1251.out","w",stdout);
    	#endif
    }
    int n;
    struct edge
    {
    	int v,nex,flow,w;
    }e[N*N];
    int head[N],cur[N],tt=1;
    void add(int x,int y,int flow,int w)
    {
    	++tt;e[tt].v=y;e[tt].flow=flow;e[tt].w=w;e[tt].nex=head[x];head[x]=tt;
    	++tt;e[tt].v=x;e[tt].flow=0;e[tt].w=-w;e[tt].nex=head[y];head[y]=tt;
    }
    int st,ed;
    const int inf=0x3f3f3f3f;
    void input()
    {
    	int x;
    	n=read<int>();
    	st=0;ed=2*n+1;
    	For(i,1,n)
    	{
    		x=read<int>();
    		add(st,i,x,0);
    		add(i+n,ed,x,0);
    	}
    	int p=read<int>(),m=read<int>(),f=read<int>(),nn=read<int>(),s=read<int>();
    	For(i,1,n)
    	{
    		if(i<n)add(i,i+1,inf,0);
    		add(st,i+n,inf,p);
    		if(i+m<=n)add(i,i+m+n,inf,f);
    		if(i+nn<=n)add(i,i+nn+n,inf,s);
    	}
    }
    ll min_cost;
    int dis[N],book[N],cnt;
    bool vis[N];
    deque<int>q;
    int spfa()
    {
    	memset(dis,inf,sizeof dis);
    	dis[st]=0;q.push_back(st);
    	int u,v;
    	while(!q.empty())
    	{
    		u=q.front();q.pop_front();vis[u]=0;
    		for(register int i=head[u];i;i=e[i].nex)
    		{
    			v=e[i].v;
    			if(e[i].flow&&cmin(dis[v],dis[u]+e[i].w))
    			{
    				if(vis[v])continue;
    				if(!q.empty()&&dis[v]<=dis[q.front()])q.push_front(v);
    				else q.push_back(v);
    				vis[v]=1;
    			}
    		}
    	}
    	return dis[ed]^inf;
    }
    int dfs(int u,int flow)
    {
    	book[u]=cnt;
    	if(u==ed)return flow;
    	int sum=0,v,f;
    	for(register int &i=cur[u];i&&flow;i=e[i].nex)
    	{
    		v=e[i].v;
    		if(book[v]^cnt&&e[i].flow&&dis[u]+e[i].w==dis[v])
    		{
    			f=dfs(v,min(flow,e[i].flow));
    			e[i].flow-=f;e[i^1].flow+=f;
    			flow-=f;sum+=f;
    			min_cost+=1ll*e[i].w*f;
    		}
    	}
    	return sum;
    }
    void work()
    {
    	while(spfa())
    	{
    		++cnt;
    		memcpy(cur,head,sizeof cur);
    		dfs(st,inf);
    	}
    	printf("%lld
    ",min_cost);
    }
    int main()
    {
    	file();
    	input();
    	work();
    	return 0;
    }
    
  • 相关阅读:
    scala-class
    uva-10422-骑士-搜索题
    HDU 5724
    HDU 5728
    CodeForces 414B
    CodeForces 698A
    Codeforces Round #363 (Div. 2)
    BestCoder 2nd Anniversary 1001 Oracle
    BestCoder 2nd Anniversary 1002 Arrange
    HDU 4798
  • 原文地址:https://www.cnblogs.com/dengyixuan/p/8185829.html
Copyright © 2011-2022 走看看