UVa 1658 - Admiral(最小费用最大流 + 拆点)
链接:
https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=4533
题意:
给出一个v(3≤v≤1000)个点e(3≤e≤10000)条边的有向加权图,
求1~v的两条不相交(除了起点和终点外没有公共点)的路径,使得权和最小。
分析:
把2到v-1的每个结点i拆成i和i'两个结点,中间连一条容量为1,费用为0的边,然后求1到v的流量为2的最小费用流即可。
本题的拆点法是解决结点容量的通用方法。
代码:
#include <cstdio>
#include <cstring>
#include <queue>
#include <vector>
using namespace std; /// 结点下标从0开始,注意maxn
struct MCMF {
static const int maxn = * + ;
static const int INF = 0x3f3f3f3f;
struct Edge {
int from, to, cap, flow, cost;
}; int n, m;
vector<Edge> edges;
vector<int> G[maxn];
int inq[maxn]; // 是否在队列中
int d[maxn]; // Bellman-Ford
int p[maxn]; // 上一条弧
int a[maxn]; // 可改进量 void init(int n) {
this->n = n;
for(int i = ; i < n; i++) G[i].clear();
edges.clear();
}
void AddEdge(int from, int to, int cap, int cost) {
edges.push_back((Edge){from, to, cap, , cost});
edges.push_back((Edge){to, from, , , -cost});
m = edges.size();
G[from].push_back(m-);
G[to].push_back(m-);
}
bool BellmanFord(int s, int t, int flow_limit, int& flow, int& cost) {
for(int i = ; i < n; i++) d[i] = INF;
memset(inq, , sizeof(inq));
d[s] = ; inq[s] = ; p[s] = ; a[s] = INF;
queue<int> Q;
Q.push(s);
while(!Q.empty()) {
int u = Q.front(); Q.pop();
inq[u] = ;
for(int i = ; i < G[u].size(); i++) {
Edge& e = edges[G[u][i]];
if(e.cap > e.flow && d[e.to] > d[u] + e.cost) {
d[e.to] = d[u] + e.cost;
p[e.to] = G[u][i];
a[e.to] = min(a[u], e.cap - e.flow);
if(!inq[e.to]) {
Q.push(e.to);
inq[e.to] = ;
}
}
}
}
if(d[t] == INF) return false;
if(flow + a[t] > flow_limit) a[t] = flow_limit - flow;
flow += a[t];
cost += d[t] * a[t];
for(int u = t; u != s; u = edges[p[u]].from) {
edges[p[u]].flow += a[t];
edges[p[u]^].flow -= a[t];
}
return true;
}
// 需要保证初始网络中没有负权圈
int MincostMaxflow(int s, int t, int flow_limit) {
int flow = , cost = ;
//while(BellmanFord(s, t, flow, cost));
while(flow < flow_limit && BellmanFord(s, t, flow_limit, flow, cost));
return cost;
}
}; MCMF mc; int main() {
int v, e;
while(~scanf("%d%d", &v, &e)) {
mc.init(v*-);
for(int i = ; i < v-; i++) mc.AddEdge(i, i+v-, , );
for(int a, b, c, i = ; i < e; i++) {
scanf("%d%d%d", &a, &b, &c);
a = (a == || a == v) ? a- : a+v-;
b--;
mc.AddEdge(a, b, , c);
}
printf("%d\n", mc.MincostMaxflow(, v-, ));
}
return ;
}
最小费用最大流模板:
/// 结点下标从0开始,注意maxn
struct MCMF {
static const int maxn = 1e3 + ;
static const int INF = 0x3f3f3f3f;
struct Edge {
int from, to, cap, flow, cost;
}; int n, m;
vector<Edge> edges;
vector<int> G[maxn];
int inq[maxn]; // 是否在队列中
int d[maxn]; // Bellman-Ford
int p[maxn]; // 上一条弧
int a[maxn]; // 可改进量 void init(int n) {
this->n = n;
for(int i = ; i < n; i++) G[i].clear();
edges.clear();
}
void AddEdge(int from, int to, int cap, int cost) {
edges.push_back((Edge){from, to, cap, , cost});
edges.push_back((Edge){to, from, , , -cost});
m = edges.size();
G[from].push_back(m-);
G[to].push_back(m-);
}
bool BellmanFord(int s, int t, int& flow, int& cost) {
for(int i = ; i < n; i++) d[i] = INF;
memset(inq, , sizeof(inq));
d[s] = ; inq[s] = ; p[s] = ; a[s] = INF;
queue<int> Q;
Q.push(s);
while(!Q.empty()) {
int u = Q.front(); Q.pop();
inq[u] = ;
for(int i = ; i < G[u].size(); i++) {
Edge& e = edges[G[u][i]];
if(e.cap > e.flow && d[e.to] > d[u] + e.cost) {
d[e.to] = d[u] + e.cost;
p[e.to] = G[u][i];
a[e.to] = min(a[u], e.cap - e.flow);
if(!inq[e.to]) {
Q.push(e.to);
inq[e.to] = ;
}
}
}
}
if(d[t] == INF) return false;
//if(flow + a[t] > flow_limit) a[t] = flow_limit - flow;
flow += a[t];
cost += d[t] * a[t];
for(int u = t; u != s; u = edges[p[u]].from) {
edges[p[u]].flow += a[t];
edges[p[u]^].flow -= a[t];
}
return true;
}
// 需要保证初始网络中没有负权圈
int MincostMaxflow(int s, int t) {
int flow = , cost = ;
while(BellmanFord(s, t, flow, cost));
//while(flow < flow_limit && BellmanFord(s, t, flow_limit, flow, cost));
return cost;
}
};
UVa 1658 - Admiral(最小费用最大流 + 拆点)的更多相关文章
- UVa 1658 Admiral(最小费用最大流)
拆点费用流 --------------------------------------------------------------------- #include<cstdio> # ...
- BZOJ-1070 修车 最小费用最大流+拆点+略坑建图
1070: [SCOI2007]修车 Time Limit: 1 Sec Memory Limit: 162 MB Submit: 3624 Solved: 1452 [Submit][Status] ...
- BZOJ-1877 晨跑 最小费用最大流+拆点
其实我是不想做这种水题的QWQ,没办法,剧情需要 1877: [SDOI2009]晨跑 Time Limit: 4 Sec Memory Limit: 64 MB Submit: 1704 Solve ...
- BZOJ-2324 营救皮卡丘 最小费用可行流+拆下界+Floyd预处理
准备一周多的期末,各种爆炸,回来后状态下滑巨快...调了一晚上+80%下午 2324: [ZJOI2011]营救皮卡丘 Time Limit: 10 Sec Memory Limit: 256 MB ...
- BZOJ-1927 星际竞速 最小费用最大流+拆点+不坑建图
1927: [Sdoi2010]星际竞速 Time Limit: 20 Sec Memory Limit: 259 MB Submit: 1593 Solved: 967 [Submit][Statu ...
- hdu 4494 Teamwork 最小费用最大流
Teamwork Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://acm.hdu.edu.cn/showproblem.php?pid=4494 ...
- bzoj 1877 [SDOI2009]晨跑(最小费用最大流)
Description Elaxia最近迷恋上了空手道,他为自己设定了一套健身计划,比如俯卧撑.仰卧起坐等 等,不过到目前为止,他坚持下来的只有晨跑. 现在给出一张学校附近的地图,这张地图中包含N个十 ...
- UVA 1658 海军上将(拆点法+最小费用限制流)
海军上将 紫书P375 这题我觉得有2个难点: 一是拆点,要有足够的想法才能把这题用网络流建模,并且知道如何拆点. 二是最小费用限制流,最小费用最大流我们都会,但如果限制流必须为一个值呢?比如这题限制 ...
- UVA - 1658 Admiral (最小费用最大流)
最短路对应费用,路径数量对应流量.为限制点经过次数,拆点为边.跑一次流量为2的最小费用最大流. 最小费用最大流和最大流EK算法是十分相似的,只是把找增广路的部分换成了求费用的最短路. #include ...
随机推荐
- 一个Java小菜鸟的实习之路
博主今年大四,六月份毕业,之前一直对编程感兴趣,于是在大学里自学了Java,(本专业是通信工程).在今年过年的时候,父母让来南方过年,于是博主自己也想着能不能在南方找份java的实习先干着,了解一下行 ...
- MySQL之函数
了解编程的人一般都会知道函数的重要性,丰富的函数有的时候可以给我们带来事半功倍的效果,在MySQL中提供了许多的内置函数,能够帮助开发人员编写简单快捷的SQL语句,除了这些内置的函数之外,用户也可以自 ...
- Linux下剪切拷贝命令
Linux下剪切拷贝命令 命令格式: mv source dest mv: 命令字 source: 源文件 dest: 目的地址 Linux下拷贝命令 命令格式:cp ...
- java导入excle表格,并且对表格进行相应的修改,并对表格数据进行整理,最后导出本地表格等一系列操作
1.首先创建一个java项目 完成效果如下图所示 2.导入以下jar包 3.代码如下 其中行和列的操作是根据需求自动划分的 public class auto_date { private stati ...
- centos7安装java开发环境
一. 安装jdk 1.进入oracle官网下载jdk-8u152-linux-x64.tar.gz,用WinScp将文件上传到/usr/local文件下 2.解压:执行命令 tar –xzvf jdk ...
- Spring课程 Spring入门篇 5-4 advice应用(上)
1 解析 1.1 通知执行顺序 2 代码演练 1 解析 1.1 通知执行顺序 aop执行方式为:前置通知==>所要增强的方法==>后置通知==>最终通知 在出现异常时会进行:前置通知 ...
- CSS 3动画
CSS 3在原来的基础上新增了变形和动画相关的属性,通过这些属性可以实现以前需要大段JavaScript才能实现的功能.css 3的变形功能可以对HTML元素执行位移.旋转.缩放.倾斜4种几何变换,借 ...
- Python-模块3-re
今天我们就说一个模块,那就是re,不过想要了解re模块,我们得先了解一下什么是正则表达式,有助于我们更好的学习re模块 一.正则表达式 首先, 我们在网页上进行注册或者登陆的时候经常能看到一些格式上的 ...
- 文本类型的HTML
<b>文本</b>加粗<i>倾斜<strong>加粗语气 工作里尽量使用strong<em>倾斜语气 工作里尽量使用em<u>下 ...
- FeatureLayer 里属性数据的提取与显示
我们用工程文件所发布的WebServer下,包含一个个图层,这些图层根据顺序进行了 0 开始的编号,这些就是FeatureLayer的地址了! FeatureLayer 包含了地图的属性信息,十分好用 ...