思路:队友贪心WA了,然后就没有然后了,自己也是第一次接触最小费用流的题。借这个题来学习一下,利用Spfa每次来找到一个最短的路径同时保存路径,每一次寻找最短路径就将这条路的最小费用流给剪掉,然后继续下次寻找最短路径。

附上代码,参考了网上,

#include<queue>
#include<cstdio>
#include<string>
#include<cstring>
#include<vector>
#include<iostream>
#include<algorithm>
#include<functional> using namespace std; const int maxn = 5e3 + ;
const int INF = 0x3f3f3f3f;
struct Edge{
int value, flow, to, rev;
Edge(){}
Edge(int a, int b, int c, int d) :to(a), value(b), flow(c), rev(d){}
};
vector<Edge> vec[maxn];
inline void Add(int from, int to, int flow, int value){
vec[from].push_back(Edge(to, value, flow, vec[to].size()));
vec[to].push_back(Edge(from, -value, , vec[from].size() - ));
}
bool book[maxn];//用于SPFA中标记是否在queue中
int cost[maxn];//用于存费用的最短路径
int pre[maxn];//用于存前结点
int pree[maxn];//用于存钱结点的vector中的下标 bool Spfa(int from, int to){
memset(book, false, sizeof book);
memset(cost, INF, sizeof cost);
book[from] = true;
//cout << cost[0] << " " << INF << endl;
cost[from] = ;
queue<int>que;
que.push(from);
while (!que.empty()){
int t = que.front();
book[t] = false;
que.pop();
for (int i = ; i < vec[t].size(); i++){
Edge& e = vec[t][i];
if (e.flow> && cost[e.to] > cost[t] + e.value){
cost[e.to] = cost[t] + e.value;
pre[e.to] = t;
pree[e.to] = i;
if (book[e.to] == false){
que.push(e.to);
book[e.to] = true;
}
}
}
}
return cost[to] != INF;
}
int Work(int from, int to){
int sum = ;
while (Spfa(from, to)){
int mflow = INF;//SPFA找到最短路径的最小容量
int flag = to;
while (flag != from){
mflow = min(mflow, vec[pre[flag]][pree[flag]].flow);
flag = pre[flag];
}
flag = to;
while (flag != from){
//cout << flag << " " << pre[flag] << " " << mflow << " " << vec[pre[flag]][pree[flag]].value << endl;
sum += vec[pre[flag]][pree[flag]].value*mflow;
vec[pre[flag]][pree[flag]].flow -= mflow;
vec[flag][vec[pre[flag]][pree[flag]].rev].flow += mflow;
flag = pre[flag];
}
}
return sum;
}
int main()
{
ios::sync_with_stdio(false); int n, m, a, b;
cin >> n >> m;
for (int i = ; i <= n; i++){
cin >> a >> b;
Add(i, a + n, , );
Add(i, b + n, , );
Add(, i, , );
}
for (int i = ; i <= m; i++){
for (int j = ; j <= ; j += ){
Add(i + n, m + n + , , j);
}
}
cout << Work(, m + n + ) << endl; return ;
}

最新文章

  1. 大熊君学习html5系列之------History API(SPA单页应用的必备------重构完结版)
  2. iOS 7.1耗电严重解决办法
  3. php Hash Table(三) Hash Table初始化
  4. C# winform post请求数据
  5. SecureCRT上传bash: rz: command not found(转载)
  6. 让aspx页面也可以通过url路由进行访问
  7. JNI|在子线程中获得JNIEnv|AttachCurrentThread
  8. 计算机网络-ip地址聚合后可用的地址数
  9. springMVC源码下载地址
  10. css(三)-- 常用属性
  11. 学习笔记——Java类和对象
  12. python操作Mysql基础
  13. 题目1010:A + B
  14. mysql(3)—— 内连接、外连接的区别
  15. [M$]微软提供的ProcessExplorer等系统工具集合
  16. (转)MSSQLSERVER执行计划详解
  17. final,finally,finalize有什么区别?String, StringBuffer, StringBuilder有什么区别?Exception和Error有什么区别?
  18. hadoop java上传文件
  19. nginx中Geoip_module模块的使用
  20. json和数组的区别

热门文章

  1. openstack 配置dnsmasq 域名解析
  2. bzoj 1059: [ZJOI2007]矩阵游戏【匈牙利算法】
  3. bzoj 1703: [Usaco2007 Mar]Ranking the Cows 奶牛排名【bitset+Floyd传递闭包】
  4. Android框架式编程之EasyPermissions
  5. Django day 33 vue中使用element-ui的使用,课程的相关介绍,vue绑定图片,课程列表接口,课程详情页面
  6. 【杂谈】HTML5到底给了我们什么?迟到的2016年终总结
  7. css为tbody或者li奇数偶数行样式
  8. 用 jQuery 实现简单倒计时功能
  9. C# 写的正整数四则运算计算器
  10. sql 获取当前季度期间