度度熊的交易计划
Time Limit: 12000/6000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 871 Accepted Submission(s): 326
Problem Description
度度熊参与了喵哈哈村的商业大会,但是这次商业大会遇到了一个难题:
喵哈哈村以及周围的村庄可以看做是一共由n个片区,m条公路组成的地区。
由于生产能力的区别,第i个片区能够花费a[i]元生产1个商品,但是最多生产b[i]个。
同样的,由于每个片区的购买能力的区别,第i个片区也能够以c[i]的价格出售最多d[i]个物品。
由于这些因素,度度熊觉得只有合理的调动物品,才能获得最大的利益。
据测算,每一个商品运输1公里,将会花费1元。
那么喵哈哈村最多能够实现多少盈利呢?
喵哈哈村以及周围的村庄可以看做是一共由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
每组测试数据包含:
第一行两个整数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
Source
直接建图
对于每个区域i s->i->t这样建图(双向边)
s->i的费用为a 流量为b
i->t的费用为-c 流量为d
倘若i j两点有联系的话 流量为INF 费用w
这样跑一边最小费用最大流
在spfa算最短路里面我们需要注意的是 每一次找到一条最短路的时候 dis[t]应该是负数 否则就是亏本 亏本的肯定不能采取
1 #include<iostream> 2 #include<cstdio> 3 #include<algorithm> 4 #include<cstring> 5 #include<cstdlib> 6 #include<string.h> 7 #include<set> 8 #include<vector> 9 #include<queue> 10 #include<stack> 11 #include<map> 12 #include<cmath> 13 typedef long long ll; 14 typedef unsigned long long LL; 15 using namespace std; 16 const double PI=acos(-1.0); 17 const double eps=0.0000000001; 18 const int INF=0x3f3f3f3f; 19 const int N=10000+100; 20 int head[N]; 21 int dis[N]; 22 int pre[N]; 23 int vis[N]; 24 int tot; 25 int m,n; 26 struct node{ 27 int from,to,next,flow,cost; 28 }edge[N<<1]; 29 void init(){ 30 memset(head,-1,sizeof(head)); 31 tot=0; 32 } 33 void add(int u,int v,int c,int cost){ 34 edge[tot].from=u; 35 edge[tot].to=v; 36 edge[tot].flow=c; 37 edge[tot].cost=cost; 38 edge[tot].next=head[u]; 39 head[u]=tot++; 40 edge[tot].from=v; 41 edge[tot].to=u; 42 edge[tot].flow=0; 43 edge[tot].cost=-cost; 44 edge[tot].next=head[v]; 45 head[v]=tot++; 46 } 47 int spfa(int s,int t){ 48 memset(pre,-1,sizeof(pre)); 49 memset(dis,INF,sizeof(dis)); 50 //cout<<dis[s]<<endl; 51 memset(vis,0,sizeof(vis)); 52 queue<int>q; 53 dis[s]=0; 54 vis[s]=1; 55 q.push(s); 56 while(!q.empty()){ 57 int x=q.front(); 58 q.pop(); 59 vis[x]=0; 60 for(int i=head[x];i!=-1;i=edge[i].next){ 61 int v=edge[i].to; 62 if(edge[i].flow&&dis[v]>dis[x]+edge[i].cost){ 63 dis[v]=edge[i].cost+dis[x]; 64 pre[v]=i; 65 if(vis[v]==0){ 66 vis[v]=1; 67 q.push(v); 68 } 69 70 } 71 } 72 } 73 if(dis[t]>0)return 0; 74 return 1; 75 } 76 int MCMF(int s,int t){ 77 int flow=0; 78 int cost=0; 79 while(spfa(s,t)){ 80 int minn=INF; 81 //cout<<3<<endl; 82 for(int i=pre[t];i!=-1;i=pre[edge[i].from]){ 83 minn=min(minn,edge[i].flow); 84 } 85 for(int i=pre[t];i!=-1;i=pre[edge[i].from]){ 86 edge[i].flow=edge[i].flow-minn; 87 edge[i^1].flow=edge[i^1].flow+minn; 88 cost=edge[i].cost*minn+cost; 89 } 90 flow=flow+minn; 91 } 92 return -cost; 93 } 94 int main(){ 95 while(scanf("%d%d",&n,&m)!=EOF){ 96 init(); 97 int s=0; 98 int t=n+100; 99 for(int i=1;i<=n;i++){ 100 int a,b,c,d; 101 scanf("%d%d%d%d",&a,&b,&c,&d); 102 add(s,i,b,a); 103 add(i,t,d,-c); 104 } 105 for(int i=1;i<=m;i++){ 106 int u,v,w; 107 scanf("%d%d%d",&u,&v,&w); 108 if(u==v)continue; 109 add(u,v,INF,w); 110 add(v,u,INF,w); 111 } 112 cout<<MCMF(s,t)<<endl; 113 } 114 }