2017百度之星初赛:B-1005. 度度熊的交易计划(最小费用流)
来源:互联网 发布:天极软件中心 编辑:程序博客网 时间:2024/05/02 01:35
度度熊的交易计划
Accepts: 460
Submissions: 2329
Time Limit: 12000/6000 MS (Java/Others)
Memory Limit: 32768/32768 K (Java/Others)
最小费用流
源点与所有点连接一条流量为最大生产数量b[i],费用为a[i]的边
所有点与汇点连接一条流量为最大出售量d[i],费用为-c[i]的边
然后如果点u和点v间有条长度为len的路径,则点u和点v连一条流量为inf,费用为len的边(注意是双向的)
这里别忘了去掉自环,重边保留最短
理论上之后求最小费用最大流就好了
但真的是最大流么?显然不一定
因为最大流也意味着所有点的商品都必须全部卖到最大出售量或者所有点的商品都买完最大生产量
这样显然是不对的,如果完全没法获得利润的话不如一个商品都不买
那怎么办
所有点与汇点再连接一条流量为最大生产数量b[i],费用为-a[i]的边就好了
这样子就相当于东西可以不买,再求的最小费用最大流就是答案了
直接套模板吧
#include<queue>#include<stdio.h>#include<string.h>#include<algorithm>using namespace std;#define LL long long#define inf 1044266558typedef struct Res{int next;int to, from;int flow, cost;}Road;Road G[2000005];int head[505], vis[505], dis[505], road[505][505], S, T, cnt, ans; int a[505], b[505], c[505], d[505];int Read(){int x = 0, f = 1;char ch;ch = getchar();while(ch<'0' || ch>'9'){if(ch=='-') f = -1;ch = getchar();}while(ch>='0' && ch<='9')x = x*10+ch-'0', ch = getchar();return x*f;}void Add(int u, int v, int flow, int cost){cnt++;G[cnt].next = head[u];head[u] = cnt;G[cnt].from = u;G[cnt].to = v;G[cnt].flow = flow;G[cnt].cost = cost;}int SPFA(){int now, i, v;queue<int> q;memset(vis, 0, sizeof(vis));memset(dis, 62, sizeof(dis));q.push(S);vis[S] = 1;dis[S] = 0;while(q.empty()==0){now = q.front();q.pop();vis[now] = 0;for(i=head[now];i!=0;i=G[i].next){v = G[i].to;if(G[i].flow && dis[v]>dis[now]+G[i].cost){dis[v] = dis[now]+G[i].cost;if(vis[v]==0){vis[v] = 1,q.push(v);}}}}if(dis[T]<inf)return 1;return 0;}int Sech(int now, int low){int i, w, used;vis[now] = 1;if(now==T)return low;used = low;for(i=head[now];i!=0;i=G[i].next){if(G[i].flow && dis[G[i].to]==dis[now]+G[i].cost && vis[G[i].to]==0){w = Sech(G[i].to, min(used, G[i].flow));G[i].flow -= w;G[i^1].flow += w;used -= w;ans += w*G[i].cost;if(used==0)return low;}}return low-used; }int main(void){int i, j, n, m, u, v, len;while(scanf("%d%d", &n, &m)!=EOF){cnt = 1;S = 0, T = n+1;memset(head, -1, sizeof(head));memset(road, 62, sizeof(road));ans = 0;for(i=1;i<=n;i++){a[i] = Read(), b[i] = Read();c[i] = Read(), d[i] = Read();}for(i=1;i<=m;i++){u = Read(), v = Read(), len = Read();if(u==v)continue;road[u][v] = road[v][u] = min(road[u][v], len);}for(i=1;i<=n;i++){Add(S, i, b[i], a[i]);Add(i, S, 0, -a[i]);Add(i, T, d[i], -c[i]);Add(T, i, 0, c[i]);Add(i, T, b[i], -a[i]);Add(T, i, 0, a[i]);}for(i=1;i<=n;i++){for(j=1;j<=n;j++){if(road[i][j]<=1000){Add(i, j, inf, road[i][j]);Add(j, i, 0, -road[i][j]);}}}while(SPFA()) {memset(vis, 0, sizeof(vis));while(Sech(S, inf))memset(vis, 0, sizeof(vis));}printf("%d\n", -ans);}return 0;}
阅读全文
1 0
- 2017百度之星初赛:B-1005. 度度熊的交易计划(最小费用流)
- 百度之星初赛(B)--度度熊的交易计划----最小费用最大流
- 百度之星初赛B 度度熊的交易计划(最小费用可行流)
- HDU 6118 度度熊的交易计划 【最小费用最大流】 (2017"百度之星"程序设计大赛
- 2017 百度之星B轮初赛(Chess, 度度熊的交易计划, 小小粉丝度度熊)
- 2017百度之星初赛(B)1005度度熊的交易计划------hdu6118
- HDU-2017"百度之星"程序设计大赛-初赛(B)-1005-度度熊的交易计划
- 度度熊的交易计划 最小费用流
- HDU 6118 度度熊的交易计划(最小费用可行流\费用流)
- HDU 6118 度度熊的交易计划 最小费用可行流
- hdu 6118 度度熊的交易计划 (最小费用最大流
- HDU 6118 度度熊的交易计划 最小费用最大流
- HDU 6118 度度熊的交易计划 (最小费用最大流)
- hdu 6118 度度熊的交易计划(最小费用可行流)
- HDU 6118 度度熊的交易计划(最小费用最大流模板)
- HDU 6118 度度熊的交易计划 (裸最小费用流)
- HDU 6118 度度熊的交易计划(最小费用可行流)
- HDU 6118 度度熊的交易计划 (最小费用流变形)
- Docker教程4
- 软件测试理论学习2017.08.13
- Pytorch中文视频教程,Pytorch实战视频教程
- git笔记
- Spring-Framework启动简介
- 2017百度之星初赛:B-1005. 度度熊的交易计划(最小费用流)
- 测试数据层
- MongDb的增删改
- 二维数组中的查找
- paramiko
- HDU 1009 FatMouse' Trade
- scikit-learn中PCA的使用方法
- vim入门小技巧
- java 程序员成长的几大成长法则