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;
    }
    
  • 相关阅读:
    服务器状态码
    QuerySet中添加Extra进行SQL查询
    django配置一个网站建设
    MySQL数据库查询中的特殊命令
    125. Valid Palindrome
    121. Best Time to Buy and Sell Stock
    117. Populating Next Right Pointers in Each Node II
    98. Validate Binary Search Tree
    91. Decode Ways
    90. Subsets II
  • 原文地址:https://www.cnblogs.com/dengyixuan/p/8185829.html
Copyright © 2011-2022 走看看