POJ2516K次费用流建图
Description:
N个订单(每个订单订K种商品),M个供应商(每个供应商供应K种商品),K种商品,后N行,表示每一个订单的详细信息,后M行表示每个供应商供应的详细信息,后K 个N * M的矩阵表示第m个供应商送第k种商品到第n个订单的花费
Solution:
建图,分商品来建,对于第k种商品:
· 源点连N个订单对于该商品的需求,费用0,容量为需求量
·N个订单对应连M个供应商,费用为第k个矩阵中对于的费用,容量为inf
·M个供应商链接汇点,费用0,容量为供应量
Code:
小错误还是很多,基本操作,一开始开的空间计算错误,加边操作中对于反向边的val和cost操作反了
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <queue>
#define inf (1 << 28)
using namespace std;
const int maxn = 111;
const int maxk = 111;
const int maxm = 111*111*2; int need[maxn][maxk];
int have[maxn][maxm];
int cost[maxm][maxn];
int allneed[maxk];
int allhave[maxk];
int n,m,k; struct node
{
int to,val,cost,pre;
}e[maxm];
int id[maxn * 4];
int cnt;
void add(int from,int to,int val,int cost)
{
e[cnt].to = to;
e[cnt].val = val;
e[cnt].cost = cost;
e[cnt].pre = id[from];
id[from] = cnt++;
swap(from,to);
e[cnt].to = to;
e[cnt].val = 0;
e[cnt].cost = -cost;
e[cnt].pre = id[from];
id[from] = cnt++;
}
void init()
{
memset(allhave,0,sizeof(allhave));
memset(allneed,0,sizeof(allneed));
memset(id,-1,sizeof(id));
cnt = 0;
}
spfa 版mcmf算法,一开始忘了加vis数组了,花费的计算算成了一整段的,应该分段计算花费
int dis[maxn];
int pre[maxn];
int path[maxn];
int vis[maxn]; bool spfa(int s,int t)
{
memset(pre,-1,sizeof(pre));
memset(vis,0,sizeof(vis));
for(int i = 0;i < maxn ;++i)
dis[i] = inf;
dis[s] = 0;
vis[s] = 1;
queue<int> q;
q.push(s);
while(q.size())
{
int now = q.front();
q.pop(); for(int i = id[now];~i;i = e[i].pre)
{
int to = e[i].to;
int val = e[i].val;
int cost = e[i].cost; if(val > 0 && dis[now] + cost < dis[to])
{
dis[to] = dis[now] + cost;
pre[to] = now;
path[to] = i;
if(!vis[to])
{
vis[to] = 1;
q.push(to);
}
}
}
vis[now] = 0;
}
if(pre[t] == -1)return false;
return true;
}
int mcmf(int s,int t)
{
int c = 0;
while(spfa(s,t))
{
int mf = inf;
for(int now = t;now != s;now = pre[now])
{
if(e[path[now]].val < mf)
mf = e[path[now]].val;
}
for(int now = t;now != s;now = pre[now])
{
e[path[now]].val -= mf;
e[path[now]^1].val += mf;
c += mf * e[path[now]].cost;
}
}
return c;
}
建图操作
对于供应商到汇点的加边操作,放错了循环……
int main()
{
int ans;//最小费用
int s,t;//源点汇点
while(~scanf("%d%d%d",&n,&m,&k),n+m+k)
{
init();
ans = 0;
s = 0;
t = n + m + 1;
//第i个订单对于第j种商品的需求量
for(int i = 1;i <= n;++i)
{
for(int j = 1;j <= k;++j)
{
scanf("%d",&need[i][j]);
allneed[j] += need[i][j];
}
}
//第i个供应商对于第j种商品的供应量
for(int i = 1;i <= m;++i)
{
for(int j = 1;j <= k;++j)
{
scanf("%d",&have[i][j]);
allhave[j] += have[i][j];
}
}
int flag = 1;//需求是否能被满足
for(int i = 1;i <= k;++i)
{
memset(id,-1,sizeof(id));
cnt = 0; if(allhave[i] < allneed[i])
flag = 0; for(int j = 1;j <= n;++j)
{
add(s,j,need[j][i],0);
for(int l = 1;l <= m;++l)
{
scanf("%d",&cost[l][j]);
if(!flag)continue;
add(j,n+l,inf,cost[l][j]);
}
}
for(int l = 1;l <= m;++l)
add(n+l,t,have[l][i],0); if(!flag)continue;
ans += mcmf(s,t);
}
if(!flag)printf("-1\n");
else printf("%d\n",ans);
}
return 0;
}
POJ2516K次费用流建图的更多相关文章
- 「SNOI2019」通信 分治优化费用流建图
题意: n 个排成一列的哨站要进行通信.第 i 个哨站的频段为 ai. 每个哨站 ii 需要选择以下二者之一: 1.直接连接到控制中心,代价为 W:2.连接到前面的某个哨站 j(j<i),代价为 ...
- Codeforces 362E Petya and Pipes 费用流建图
题意: 给一个网络中某些边增加容量,增加的总和最大为K,使得最大流最大. 费用流:在某条边增加单位流量的费用. 那么就可以2个点之间建2条边,第一条给定边(u,v,x,0)这条边费用为0 同时另一条边 ...
- hdu4411 经典费用里建图
题意: 给以一个无向图,0 - n,警察在0,他们有k个警队,要派一些警队去1--n个城市抓小偷, 问所有吧所有小偷全抓到然后在返回0的最小路径和是多少,当地i个城市被攻击的时候他会通知i ...
- hdu4106 区间k覆盖问题(连续m个数,最多选k个数) 最小费用最大流 建图巧妙
/** 题目:hdu4106 区间k覆盖问题(连续m个数,最多选k个数) 最小费用最大流 建图巧妙 链接:http://acm.hdu.edu.cn/showproblem.php?pid=4106 ...
- poj3680 Intervals 区间k覆盖问题 最小费用最大流 建图巧妙
/** 题目:poj3680 Intervals 区间k覆盖问题 最小费用最大流 建图巧妙 链接:http://poj.org/problem?id=3680 题意:给定n个区间,每个区间(ai,bi ...
- poj 3281 最大流+建图
很巧妙的思想 转自:http://www.cnblogs.com/kuangbin/archive/2012/08/21/2649850.html 本题能够想到用最大流做,那真的是太绝了.建模的方法很 ...
- 图论--网络流--最小割 HDU 2485 Destroying the bus stations(最短路+限流建图)
Problem Description Gabiluso is one of the greatest spies in his country. Now he's trying to complet ...
- 图论--网络流--最大流--POJ 3281 Dining (超级源汇+限流建图+拆点建图)
Description Cows are such finicky eaters. Each cow has a preference for certain foods and drinks, an ...
- poj 2135 Farm Tour 最小费用最大流建图跑最短路
题目链接 题意:无向图有N(N <= 1000)个节点,M(M <= 10000)条边:从节点1走到节点N再从N走回来,图中不能走同一条边,且图中可能出现重边,问最短距离之和为多少? 思路 ...
随机推荐
- Android 开发 深入理解Handler、Looper、Messagequeue 转载
转载请注明出处:http://blog.csdn.net/vnanyesheshou/article/details/73484527 本文已授权微信公众号 fanfan程序媛 独家发布 扫一扫文章底 ...
- 微信小程序版本管理
备忘录:<需要修改完善> 打开小程序开发者工具,点击版本管理,点击设置 , 通用更改码云的名字和邮箱 网络认证选择用户名和密码 把密码输入了,点击远程 添加 输入码云的https地址 和仓 ...
- ORACLE日常操作手册
转发自:http://blog.csdn.net/lichangzai/article/details/7955766 以前为开发人员编写的oracle基础操作手册,都基本的oracle操作和SQL语 ...
- PHP实现JS点击点击定位
点击class='women' 定位到 class='m=foot'$(".women").on('click',function(){ $("html, body&qu ...
- .NET MVC 控制器和行为
行为就是可访问方法(public) 行为返回类型必须是 ActionResult 或者其派生类,基本上返回类型为以下四种之一 View(视图路径) Json(对象或者对象集合) Content(字符串 ...
- Django之form模板的使用
form模块的简介与用处 1.form 是前后端交互的一种方式, form表单提交的一种,django中有一个模块是form他主要用处就过滤前端form提交的数据 1. forms 模块是处理前后台的 ...
- svg矢量图
svg简介 Scalable Vector Graphics 可缩放矢量图形 SVG 图像在放大或改变尺寸的情况下其图形质量不会有所损失 svg知识点 svg如何绘图 svg和cnavas区别 svg ...
- hdoj4734(数位dp优化)
题目链接:https://vjudge.net/problem/HDU-4734 题意:定义一个十进制数AnAn-1...A1的value为An*2n-1+...+A1*20,T组样例(<=1e ...
- 100-days: twelve
Title: Mark Zuckerberg wants Facebook's to emulate China's WeChat, but can it? emulate v.效仿,模仿 As ...
- 清理xcode
移除 Xcode 运行安装 APP 产生的缓存文件(DerivedData) ~/Library/Developer/Xcode/DerivedData 移除 APP 打包的ipa历史版本(Archi ...