Problem Description
度度熊参与了喵哈哈村的商业大会,但是这次商业大会遇到了一个难题:
喵哈哈村以及周围的村庄可以看做是一共由n个片区,m条公路组成的地区。
由于生产能力的区别,第i个片区能够花费a[i]元生产1个商品,但是最多生产b[i]个。
同样的,由于每个片区的购买能力的区别,第i个片区也能够以c[i]的价格出售最多d[i]个物品。
由于这些因素,度度熊觉得只有合理的调动物品,才能获得最大的利益。
据测算,每一个商品运输1公里,将会花费1元。
那么喵哈哈村最多能够实现多少盈利呢?
Input
本题包含若干组测试数据。
每组测试数据包含:
第一行两个整数n,m表示喵哈哈村由n个片区、m条街道。
接下来n行,每行四个整数a[i],b[i],c[i],d[i]表示的第i个地区,能够以a[i]的价格生产,最多生产b[i]个,以c[i]的价格出售,最多出售d[i]个。
接下来m行,每行三个整数,u[i],v[i],k[i],表示该条公路连接u[i],v[i]两个片区,距离为k[i]
可能存在重边,也可能存在自环。
满足:
1<=n<=500,
1<=m<=1000,
1<=a[i],b[i],c[i],d[i],k[i]<=1000,
1<=u[i],v[i]<=n
Output
输出最多能赚多少钱。
Sample Input
2 1
5 5 6 1
3 5 7 7
1 2 1
Sample Output
23
题意
如上
题解
超级源点S=0,超级汇点T=n+1
对于每个a,b,c,d
建图从源点到i建边,流量为b花费为a,从i到汇点建边,流量为d花费为-c
最后每个u,v建边,流量INF,花费dis
跑一个S到T的最小费用最大流,由于每个花费都取反了,所以跑出来的值就是最大费用最大流
这里有个坑点是如果源点到汇点的距离DIST[T]>0说明以后的增广路都是亏钱,就可以直接跳出循环
代码
1 #include<bits/stdc++.h> 2 using namespace std; 3 4 const int N=1e5+5; 5 const int M=2e5+5; 6 const int INF=0x3f3f3f3f; 7 8 int FIR[N],FROM[M],TO[M],CAP[M],FLOW[M],COST[M],NEXT[M],tote; 9 int pre[N],dist[N],q[400000]; 10 bool vis[N]; 11 int n,m,S,T; 12 void init() 13 { 14 tote=0; 15 memset(FIR,-1,sizeof(FIR)); 16 } 17 void addEdge(int u,int v,int cap,int cost) 18 { 19 FROM[tote]=u; 20 TO[tote]=v; 21 CAP[tote]=cap; 22 FLOW[tote]=0; 23 COST[tote]=cost; 24 NEXT[tote]=FIR[u]; 25 FIR[u]=tote++; 26 27 FROM[tote]=v; 28 TO[tote]=u; 29 CAP[tote]=0; 30 FLOW[tote]=0; 31 COST[tote]=-cost; 32 NEXT[tote]=FIR[v]; 33 FIR[v]=tote++; 34 } 35 bool SPFA(int s, int t) 36 { 37 memset(dist,INF,sizeof(dist)); 38 memset(vis,false,sizeof(vis)); 39 memset(pre,-1,sizeof(pre)); 40 dist[s] = 0;vis[s]=true;q[1]=s; 41 int head=0,tail=1; 42 while(head!=tail) 43 { 44 int u=q[++head];vis[u]=false; 45 for(int v=FIR[u];v!=-1;v=NEXT[v]) 46 { 47 if(dist[TO[v]]>dist[u]+COST[v]&&CAP[v]>FLOW[v]) 48 { 49 dist[TO[v]]=dist[u]+COST[v]; 50 pre[TO[v]]=v; 51 if(!vis[TO[v]]) 52 { 53 vis[TO[v]] = true; 54 q[++tail]=TO[v]; 55 } 56 } 57 } 58 } 59 if(dist[t]>0)return false;//亏钱 60 return pre[t]!=-1; 61 } 62 void MCMF(int s, int t, int &cost, int &flow) 63 { 64 flow=0; 65 cost=0; 66 while(SPFA(s,t)) 67 { 68 int Min = INF; 69 for(int v=pre[t];v!=-1;v=pre[TO[v^1]]) 70 Min = min(Min, CAP[v]-FLOW[v]); 71 for(int v=pre[t];v!=-1;v=pre[TO[v^1]]) 72 { 73 FLOW[v]+=Min; 74 FLOW[v^1]-=Min; 75 cost+=COST[v]*Min; 76 } 77 flow+=Min; 78 } 79 } 80 int main() 81 { 82 while(scanf("%d%d",&n,&m)!= EOF) 83 { 84 init(); 85 S=0,T=n+1; 86 int u,v,a,b,c,d; 87 for(int i=1;i<=n;i++) 88 { 89 scanf("%d%d%d%d",&a,&b,&c,&d); 90 addEdge(S,i,b,a); 91 addEdge(i,T,d,-c); 92 } 93 for(int i=1;i<=m;i++) 94 { 95 scanf("%d%d%d",&u,&v,&d); 96 addEdge(u,v,0x3f3f3f3f,d); 97 addEdge(v,u,0x3f3f3f3f,d); 98 } 99 int cost,flow; 100 MCMF(S,T,cost,flow); 101 printf("%d ",-cost); 102 } 103 return 0; 104 }