HDU6118-度度熊的交易计划(最小可行流)
2017-08-15 20:19
309 查看
度度熊的交易计划
Time Limit: 12000/6000 MS (Java/Others) Memory Limit: 32768/32768K (Java/Others)
Total Submission(s): 919 Accepted Submission(s): 343
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
Sourc
2017"百度之星"程序设计大赛
- 初赛(B)
解题思路:先预处理出一件第i个区域生产的物品卖到第j个区域生产的物品盈利的钱,那么就可以开始拆点建边,源点0向1~n连边,容量为能生产的量,费用为0,n+1~2*n向汇点连边,容量为能出售的量,费用为0,1~n和n+1~2*n之间两两连边,容量为INF,费用为负的盈利值(盈利值为非负的才建边),然后跑一遍最小费用可行流即可
#include <iostream> #include <cstdio> #include <cstring> #include <string> #include <algorithm> #include <map> #include <set> #include <stack> #include <queue> #include <vector> #include <bitset> #include <functional> using namespace std; #define LL long long const int INF = 0x3f3f3f3f; const int maxn = 2100; const int MAXM = 300000; int n, m; int dis[maxn], vis[maxn]; int s[maxn], nt[maxn], e[maxn], l[maxn]; int mp[505][505]; int aa[maxn], bb[maxn], cc[maxn], dd[maxn], pre[maxn], a[maxn], d[maxn]; struct node { int id, dis; bool operator<(const node &a)const { return dis > a.dis; } }pre1, nt1; int cnt; struct Edge { int u, v, c, cost, next; } edge[MAXM]; void init() { cnt = 0; memset(s, -1, sizeof(s)); } void add(int u, int v, int c, int cost) { edge[cnt].u = u; edge[cnt].v = v; edge[cnt].cost = cost; edge[cnt].c = c; edge[cnt].next = s[u]; s[u] = cnt++; edge[cnt].u = v; edge[cnt].v = u; edge[cnt].cost = -cost; edge[cnt].c = 0; edge[cnt].next = s[v]; s[v] = cnt++; } bool spfa(int ss, int ee, int &flow, int &cost) { queue<int> q; memset(d, INF, sizeof d); memset(vis, 0, sizeof vis); d[ss] = 0, vis[ss] = 1, pre[ss] = 0, a[ss] = INF; q.push(ss); while (!q.empty()) { int u = q.front(); q.pop(); vis[u] = 0; for (int i = s[u]; ~i; i = edge[i].next) { int v = edge[i].v; if (edge[i].c>0 && d[v]>d[u] + edge[i].cost) { d[v] = d[u] + edge[i].cost; pre[v] = i; a[v] = min(a[u], edge[i].c); if (!vis[v]) { vis[v] = 1; q.push(v); } } } } if (d[ee] == INF) return 0; if (cost + d[ee] * a[ee] > cost) return 0;//最小费用流去掉这行即可 flow += a[ee]; cost += d[ee] * a[ee]; int u = ee; while (u != ss) { edge[pre[u]].c -= a[ee]; edge[pre[u] ^ 1].c += a[ee]; u = edge[pre[u]].u; } return 1; } int MCMF(int ss, int ee) { int cost = 0, flow = 0; while (spfa(ss, ee, flow, cost)); return cost; } void Dijkstra(int ss) { priority_queue<node>q; memset(vis, 0, sizeof vis); memset(dis, INF, sizeof dis); dis[ss] = 0; pre1.id = ss, pre1.dis = 0; q.push(pre1); while (!q.empty()) { pre1 = q.top(); q.pop(); vis[pre1.id] = 1; for (int i = s[pre1.id]; ~i; i = nt[i]) { if (vis[e[i]]) continue; if (dis[e[i]] > dis[pre1.id] + l[i]) { dis[e[i]] = dis[pre1.id] + l[i]; nt1.id = e[i], nt1.dis = dis[e[i]]; q.push(nt1); } } } for (int i = 1; i <= n; i++) mp[ss][i] = dis[i]; } int main() { while (~scanf("%d%d", &n, &m)) { memset(s, -1, sizeof s); cnt = 0; for (int i = 1; i <= n; i++) scanf("%d%d%d%d", &aa[i], &bb[i], &cc[i], &dd[i]); for (int i = 1; i <= m; i++) { int u, v, k; scanf("%d%d%d", &u, &v, &k); nt[cnt] = s[u], s[u] = cnt, e[cnt] = v, l[cnt++] = k; nt[cnt] = s[v], s[v] = cnt, e[cnt] = u, l[cnt++] = k; } for (int i = 1; i <= n; i++) Dijkstra(i); for (int i = 1; i <= n; i++) for (int j = 1; j <= n; j++) mp[i][j] = cc[j] - aa[i] - mp[i][j]; init(); for (int i = 1; i <= n; i++) { add(0, i, bb[i], 0); add(i + n, 2 * n + 1, dd[i], 0); } for (int i = 1; i <= n; i++) for (int j = 1; j <= n; j++) if (mp[i][j] > 0) add(i, j + n, INF, -mp[i][j]); printf("%d\n", -MCMF(0, 2 * n + 1)); } return 0; }
相关文章推荐
- HDU6118:度度熊的交易计划(入门级最小费用可行流)
- hdu 6118 度度熊的交易计划(最小费用可行流)
- 百度之星初赛B 度度熊的交易计划(最小费用可行流)
- HDU 6118 度度熊的交易计划(最小费用可行流)
- [HDOJ6118] 度度熊的交易计划(最小费用可行流)
- hdu 6118 度度熊的交易计划 (最小费用最大流
- [HDU6118][2017"百度之星"程序设计大赛 - 初赛(B)]度度熊的交易计划
- hdu 6118 度度熊的交易计划 (最小费用最大流
- [HDU6118][2017"百度之星"程序设计大赛 - 初赛(B)]度度熊的交易计划
- hdu 6118 度度熊的交易计划 (最小费用最大流
- Hdu6118 度度熊的交易计划(2017"百度之星"程序设计大赛 - 初赛(B))
- hdu 6118 度度熊的交易计划 (最小费用最大流
- hdu 6118 度度熊的交易计划 (最小费用最大流
- 2017百度之星初赛(B)1005度度熊的交易计划------hdu6118
- HDU6118 度度熊的交易计划 【费用流】
- hdu 6118 度度熊的交易计划 (最小费用最大流
- hdu 6118 度度熊的交易计划 (最小费用最大流
- HDU 6118 度度熊的交易计划 (最小费用最大流模板题)
- bzoj 3876: [Ahoi2014]支线剧情 (无源汇最小费用可行流)[省选计划系列]
- hdu 6118 度度熊的交易计划 (最小费用最大流