zoukankan      html  css  js  c++  java
  • P4015 运输问题

    (color{#0066ff}{题目描述})

    W 公司有 m 个仓库和 n 个零售商店。第 i 个仓库有 (a_i) 个单位的货物;第 j 个零售商店需要 (b_j) 个单位的货物。

    货物供需平衡,即(sumlimits_{i=1}^{m}a_i=sumlimits_{j=1}^{n}b_j)

    从第 i 个仓库运送每单位货物到第 j 个零售商店的费用为 (c_{ij})​ 。

    试设计一个将仓库中所有货物运送到零售商店的运输方案,使总运输费用最少。

    (color{#0066ff}{输入格式})

    第 1 行有 2 个正整数 m 和 n,分别表示仓库数和零售商店数。

    接下来的一行中有 m 个正整数 (a_i),表示第 i 个仓库有 (a_i) 个单位的货物。

    再接下来的一行中有 n 个正整数 (b_j),表示第 j 个零售商店需要 (b_j) 个单位的货物。

    接下来的 m 行,每行有 n 个整数,表示从第 i 个仓库运送每单位货物到第 j 个零售商店的费用 (c_{ij})

    (color{#0066ff}{输出格式})

    两行分别输出最小运输费用和最大运输费用。

    (color{#0066ff}{输入样例})

    2 3
    220 280
    170 120 210
    77 39 105
    150 186 122
    

    (color{#0066ff}{输出样例})

    48500
    69140
    

    (color{#0066ff}{数据范围与提示})

    1≤n,m≤100

    (color{#0066ff}{题解})

    S向每个仓库连容量为仓库货物量,边权为0的边(保证每个仓库的流出量)

    仓库向商店连容量为仓库货物量,边权为运输费用的边

    每个商店向T连容量为所需量,边权为0的边(保证所需)

    建正边跑Dinic,在取相反数重新来

    #include<cstdio>
    #include<iostream>
    #include<cstring>
    #include<algorithm>
    #include<queue>
    #include<cmath>
    #define _ 0
    #define LL long long
    inline LL in()
    {
    	LL x=0,f=1; char ch;
    	while(!isdigit(ch=getchar()))(ch=='-')&&(f=-f);
    	while(isdigit(ch)) x=x*10+(ch^48),ch=getchar();
    	return x*f;
    }
    const LL inf=99999999999999999LL;
    struct node{int to,nxt; LL dis,cap;}e[105050];
    int cnt=1;
    std::queue<int> q;
    LL dis[555],change[555];
    int n,m,s,t;
    int head[555],road[555];
    LL vala[555],valb[555];
    bool vis[555];
    LL val[555][555];
    inline void add(int from,int to,LL cap,LL dis)
    {
    	cnt++;
    	e[cnt].to=to;
    	e[cnt].dis=dis;
    	e[cnt].cap=cap;
    	e[cnt].nxt=head[from];
    	head[from]=cnt;
    }
    inline bool spfa()
    {
    	for(int i=s;i<=t;i++) dis[i]=inf,change[i]=inf,vis[i]=0;
    	dis[s]=0;
    	q.push(s);
    	while(!q.empty())
    	{
    		int tp=q.front(); q.pop();
    		vis[tp]=false;
    		for(int i=head[tp];i;i=e[i].nxt)
    		{
    			int go=e[i].to;
    			if(dis[go]>dis[tp]+e[i].dis&&e[i].cap>0)
    			{
    				dis[go]=dis[tp]+e[i].dis;
    				road[go]=i;
    				change[go]=std::min(change[tp],e[i].cap);
    				if(!vis[go])
    				{
    					vis[go]=true;
    					q.push(go);
    				}
    			}
    		}
    	}
    	return change[t]!=inf;
    }
    inline void mcmf(int flag)
    {
    	LL flow=0,cost=0;
    	while(spfa())
    	{
    		flow+=change[t];
    		cost+=change[t]*dis[t];
    		for(int o=t;o!=s;o=e[road[o]^1].to)
    		{
    			e[road[o]].cap-=change[t];
    			e[road[o]^1].cap+=change[t];
    		}
    	}
    	printf("%lld
    ",cost*flag);
    }
    int main()
    {
    	m=in(),n=in();
    	t=n+m+1,s=0;
    	for(int i=1;i<=m;i++) add(s,i,vala[i]=in(),0),add(i,s,0,0);
    	for(int i=1;i<=n;i++) add(i+m,t,valb[i]=in(),0),add(t,i+m,0,0);
    	for(int i=1;i<=m;i++)
    		for(int j=1;j<=n;j++)
    		{
    			val[i][j]=in();
    			add(i,j+m,vala[i],val[i][j]);
    			add(j+m,i,0,-val[i][j]);
    		}
    	mcmf(1);
    	cnt=1;
    	for(int i=s;i<=t;i++) head[i]=0;
    	for(int i=1;i<=m;i++) add(s,i,vala[i],0),add(i,s,0,0);
    	for(int i=1;i<=n;i++) add(i+m,t,valb[i],0),add(t,i+m,0,0);
    	for(int i=1;i<=m;i++)
    		for(int j=1;j<=n;j++)
    		{
    			add(i,j+m,vala[i],-val[i][j]);
    			add(j+m,i,0,val[i][j]);
    		}
    	mcmf(-1);
    	return 0;
    }
    
  • 相关阅读:
    storyboard文件的认识
    设置程序启动时加载的storyboard
    IBAction和IBOutlet
    listview
    JDK下载地址
    [置顶] Docker学习总结(2)——Docker实战之入门以及Dockerfile(二)
    [置顶] Docker学习总结(1)——Docker实战之入门以及Dockerfile(一)
    [置顶] Docker学习总结(1)——Docker实战之入门以及Dockerfile(一)
    XML学习总结(2)——XML简单介绍
    XML学习总结(2)——XML简单介绍
  • 原文地址:https://www.cnblogs.com/olinr/p/10098170.html
Copyright © 2011-2022 走看看