luogu4015: 运输问题(网络流/最小费用最大流/最大费用最大流)
2018-03-23 15:16
1336 查看
题目链接
裸题,不用思考构图。
题目大意:
1 一个二分图,x集合是仓库,y集合是店面,每个x都通全部的y;
2 求:将x集合中全部的货物转移到y集合,最小费用和最大费用分别是多少。
解题思路:
1 网络流最难的一直是构图,但这题的图非常简单;
2 构图思路:(源点-〉x集合), (y集合 -〉汇点) ,( x-〉y);
3 最小费用最大流不难,直接用spfa来分层,然后回溯封路就好;
4 最大费用最大流:把费用取负,然后就变成了最小费用了~~输出取反就好!!
5 ps:对于点的结构体,多了一个c参数,为了推流量的时候用的。
上代码:#include<cstdio>
#include<algorithm>
using namespace std;
const int inf=999999999;
int n,m,st,ed,len,tou,wei;
int na[110],nb[110],nc[110][110],l[50005];
struct nodx{int h,f,d,v,x,c;}a[500];
struct nodb{int x,y,c,d,gg,f;}b[50005];
void ins(int x,int y,int c,int d)
{
len++;b[len].x=x;b[len].y=y;b[len].c=c;b[len].d=d;
b[len].gg=a[x].h;a[x].h=len;b[len].f=len+1;
len++;b[len].x=y;b[len].y=x;b[len].c=0;b[len].d=-d;
b[len].gg=a[y].h;a[y].h=len;b[len].f=len-1;
}
void bt(int k)//构图函数
{
len=0;
for(int i=st;i<=ed;i++) a[i].h=0;
for(int i=1;i<=m;i++) ins(st,i,na[i],0); //st->仓库
for(int i=1;i<=n;i++) ins(i+m,ed,nb[i],0);//店面->ed
for(int i=1;i<=m;i++)//仓库->店面
{
for(int j=1;j<=n;j++)
{
ins(i,j+m,na[i],nc[i][j]*k); //从x->y最多的数量 就是 x 有的数量
}
}
}
bool spfa()
{
for(int i=0;i<=ed;i++) { a[i].v=0;a[i].d=inf; }
a[st].v=1;a[st].d=0;a[st].c=inf;
l[1]=st;tou=1;wei=2;
while(tou!=wei)
{
int x=l[tou];
for(int i=a[x].h;i>0;i=b[i].gg)
{
int y=b[i].y;
if(a[y].d>a[x].d+b[i].d&&b[i].c>0)
{
a[y].d=a[x].d+b[i].d;
a[y].x=x;//记录来时的x
a[y].f=i;//记录来时的路
a[y].c=min(a[x].c,b[i].c);//记录该点获取的流量
if(a[y].v==0)
{
a[y].v=1;l[wei++]=y;if(wei>ed) wei=1;
}
}
}
a[x].v=0; tou++; if(tou>ed)tou=1;
}
if(a[ed].d!=inf)
{
for(int x=ed;x!=st;x=a[x].x)//把整条路的流量更改(封路)
{
int i=a[x].f;
b[i].c-=a[ed].c;
b[b[i].f].c+=a[ed].c;
}
return 1;
}
return 0;
}
int flow()
{
int ans=0;
while(spfa())
{
ans+=a[ed].c*a[ed].d;//流量*单价
}
return ans;
}
int main()
{
scanf("%d %d",&m,&n);int x,y;
st=0;ed=n+m+1;
for(int i=1;i<=m;i++) scanf("%d",&na[i]);
for(int i=1;i<=n;i++) scanf("%d",&nb[i]);
for(int i=1;i<=m;i++)
{
for(int j=1;j<=n;j++)
{
scanf("%d",&nc[i][j]);
}
}
bt(1);//先构最小费用的图
printf("%d\n",flow());
bt(-1);//再构最大费用的图
printf("%d\n",-flow()); //输出取反
return 0;
}
裸题,不用思考构图。
题目大意:
1 一个二分图,x集合是仓库,y集合是店面,每个x都通全部的y;
2 求:将x集合中全部的货物转移到y集合,最小费用和最大费用分别是多少。
解题思路:
1 网络流最难的一直是构图,但这题的图非常简单;
2 构图思路:(源点-〉x集合), (y集合 -〉汇点) ,( x-〉y);
3 最小费用最大流不难,直接用spfa来分层,然后回溯封路就好;
4 最大费用最大流:把费用取负,然后就变成了最小费用了~~输出取反就好!!
5 ps:对于点的结构体,多了一个c参数,为了推流量的时候用的。
上代码:#include<cstdio>
#include<algorithm>
using namespace std;
const int inf=999999999;
int n,m,st,ed,len,tou,wei;
int na[110],nb[110],nc[110][110],l[50005];
struct nodx{int h,f,d,v,x,c;}a[500];
struct nodb{int x,y,c,d,gg,f;}b[50005];
void ins(int x,int y,int c,int d)
{
len++;b[len].x=x;b[len].y=y;b[len].c=c;b[len].d=d;
b[len].gg=a[x].h;a[x].h=len;b[len].f=len+1;
len++;b[len].x=y;b[len].y=x;b[len].c=0;b[len].d=-d;
b[len].gg=a[y].h;a[y].h=len;b[len].f=len-1;
}
void bt(int k)//构图函数
{
len=0;
for(int i=st;i<=ed;i++) a[i].h=0;
for(int i=1;i<=m;i++) ins(st,i,na[i],0); //st->仓库
for(int i=1;i<=n;i++) ins(i+m,ed,nb[i],0);//店面->ed
for(int i=1;i<=m;i++)//仓库->店面
{
for(int j=1;j<=n;j++)
{
ins(i,j+m,na[i],nc[i][j]*k); //从x->y最多的数量 就是 x 有的数量
}
}
}
bool spfa()
{
for(int i=0;i<=ed;i++) { a[i].v=0;a[i].d=inf; }
a[st].v=1;a[st].d=0;a[st].c=inf;
l[1]=st;tou=1;wei=2;
while(tou!=wei)
{
int x=l[tou];
for(int i=a[x].h;i>0;i=b[i].gg)
{
int y=b[i].y;
if(a[y].d>a[x].d+b[i].d&&b[i].c>0)
{
a[y].d=a[x].d+b[i].d;
a[y].x=x;//记录来时的x
a[y].f=i;//记录来时的路
a[y].c=min(a[x].c,b[i].c);//记录该点获取的流量
if(a[y].v==0)
{
a[y].v=1;l[wei++]=y;if(wei>ed) wei=1;
}
}
}
a[x].v=0; tou++; if(tou>ed)tou=1;
}
if(a[ed].d!=inf)
{
for(int x=ed;x!=st;x=a[x].x)//把整条路的流量更改(封路)
{
int i=a[x].f;
b[i].c-=a[ed].c;
b[b[i].f].c+=a[ed].c;
}
return 1;
}
return 0;
}
int flow()
{
int ans=0;
while(spfa())
{
ans+=a[ed].c*a[ed].d;//流量*单价
}
return ans;
}
int main()
{
scanf("%d %d",&m,&n);int x,y;
st=0;ed=n+m+1;
for(int i=1;i<=m;i++) scanf("%d",&na[i]);
for(int i=1;i<=n;i++) scanf("%d",&nb[i]);
for(int i=1;i<=m;i++)
{
for(int j=1;j<=n;j++)
{
scanf("%d",&nc[i][j]);
}
}
bt(1);//先构最小费用的图
printf("%d\n",flow());
bt(-1);//再构最大费用的图
printf("%d\n",-flow()); //输出取反
return 0;
}
相关文章推荐
- 线性规划与网络流24题の17 运输问题(最小费用最大流、最大费用最大流)
- 洛谷 P4015 运输问题 【最小费用最大流+最大费用最大流】
- [网络流24题] 17 运输问题(网络费用流量,最小费用最大流)
- 线性规划与网络流24题の18 分配问题(最小费用最大流、最大费用最大流)
- 线性规划与网络流24题之分配问题 最大费用最大流、最小费用最大流、二分图的最佳匹配
- 【费用流】【网络流24题】【cogs 739】运输问题
- 【网络流24题】No.21 (最长 k 可重区间集问题 最长不相交路径 最大费用流)
- 739. [网络流24题] 运输问题 费用流/求最大最小值
- 【网络流24题】运输问题(费用流)
- 网络流最大流ISAP算法【草地排水】【运输问题1】(水题)
- Libre 6011 「网络流 24 题」运输问题 (网络流,最小费用最大流)
- 【网络流24题】分配问题 最小最大费用最大流
- 【网络流24题】No. 17 运输问题 (费用流)
- 网络流相关算法总结,最大流EK算法,SAP算法,最小费用最大流,最小费用路算法,最大流最小割定理
- nefu494深海机器人问题【网络流24题】最大费用流
- 740. [网络流24题] 分配问题 费用流/求最大最小费用
- [题解] [网络流二十四题(十一)] 航空路线问题(最大费用最大流)
- loj6011「网络流 24 题」运输问题(费用流)
- 【网络流24题】No.11(航空路线问题 最长不相交路径 最大费用流)
- 【网络流24题】航空路线问题(最大费用流)