您的位置:首页 > 其它

ZOJ3362 Beer Problem(最小费用任意流)

2016-04-08 18:27 113 查看
题目大概说有n个城市,由m条无向边相连,每条边每天最多运送cap桶酒且其运送一桶的花费是cost。现在从1号城市开始出发运酒,供应到2到n号城市,这些城市的收购单价是price,问最大的盈利是多少。

。。。顺路AC

#include<cstdio>
#include<cstring>
#include<queue>
#include<algorithm>
using namespace std;
#define INF (1<<30)
#define MAXN 111
#define MAXM 111*222
struct Edge{
int u,v,cap,cost,next;
}edge[MAXM];
int head[MAXN];
int NV,NE,vs,vt;

void addEdge(int u,int v,int cap,int cost){
edge[NE].u=u; edge[NE].v=v; edge[NE].cap=cap; edge[NE].cost=cost;
edge[NE].next=head[u]; head[u]=NE++;
edge[NE].u=v; edge[NE].v=u; edge[NE].cap=0; edge[NE].cost=-cost;
edge[NE].next=head[v]; head[v]=NE++;
}
bool vis[MAXN];
int d[MAXN],pre[MAXN];
bool SPFA(){
for(int i=0;i<NV;++i){
vis[i]=0;
d[i]=INF;
}
vis[vs]=1;
d[vs]=0;
queue<int> que;
que.push(vs);
while(!que.empty()){
int u=que.front(); que.pop();
for(int i=head[u]; i!=-1; i=edge[i].next){
int v=edge[i].v;
if(edge[i].cap && d[v]>d[u]+edge[i].cost){
d[v]=d[u]+edge[i].cost;
pre[v]=i;
if(!vis[v]){
vis[v]=1;
que.push(v);
}
}
}
vis[u]=0;
}
return d[vt]!=INF;
}
int MCMF(){
int res=0;
while(SPFA()){
int flow=INF,cost=0;
for(int u=vt; u!=vs; u=edge[pre[u]].u){
flow=min(flow,edge[pre[u]].cap);
}
for(int u=vt; u!=vs; u=edge[pre[u]].u){
edge[pre[u]].cap-=flow;
edge[pre[u]^1].cap+=flow;
cost+=flow*edge[pre[u]].cost;
}
if(cost>=0) break;
res+=cost;
}
return res;
}
int main(){
int n,m,a,b,c,d;
while(~scanf("%d%d",&n,&m)){
vs=1; vt=n+1; NV=vt+1; NE=0;
memset(head,-1,sizeof(head));
for(int i=2; i<=n; ++i){
scanf("%d",&a);
addEdge(i,vt,INF,-a);
}
while(m--){
scanf("%d%d%d%d",&a,&b,&c,&d);
addEdge(a,b,c,d);
addEdge(b,a,c,d);
}
printf("%d\n",-MCMF());
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: