UVA1658 Admiral 拆点法解决结点容量(路径不能有公共点,容量为1的时候) 最小费用最大流
/**
题目:UVA1658 Admiral
链接:https://vjudge.net/problem/UVA-1658
题意:lrj入门经典P375
求从s到t的两条不相交(除了s和t外,没有公共点)的路径,使得权值和最小。 思路:拆点法。
除了s,t外。把其他点都拆成两个。 例如点A,拆成A和A'。A指向A'连一条容量为1,花费为0的边。
原来指向A的,仍然指向A点。
原来A指向其他点的,由A'指向它们。 最小费用最大流求流量为2时候的最小费用即可。 */
#include<iostream>
#include<cstring>
#include<vector>
#include<map>
#include<cstdio>
#include<algorithm>
#include<queue>
using namespace std;
const int INF = 0x3f3f3f3f;
typedef long long LL;
const int N = ;
struct Edge{
int from, to, cap, flow, cost;
Edge(int u,int v,int c,int f,int w):from(u),to(v),cap(c),flow(f),cost(w){}
};
struct MCMF{
int n, m;
vector<Edge> edges;
vector<int> G[N];
int inq[N];
int d[N];
int p[N];
int a[N]; 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,long long 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,long long &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;
flow += a[t];
cost += (long long)d[t]*(long long)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];
}
///流量为2时的最小费用。
if(flow==){
return false;
}
return true;
}
int MincostMaxflow(int s,int t,long long &cost){
int flow = ;
cost = ;
while(BellmanFord(s,t,flow,cost));
return flow;
}
};
vector<int>node[N];
int main()
{
int n, m;
while(scanf("%d%d",&n,&m)==)
{
int s = , t = n;
int u, v;
long long cost;
MCMF mcmf;
mcmf.init(n*);
for(int i = ; i <= n; i++) node[i].clear();
for(int i = ; i < m; i++){
scanf("%d%d%lld",&u,&v,&cost);
node[u].push_back(v);
node[u].push_back(cost);
}
int tot = n+;
for(int i = ; i < node[].size(); i+=){
mcmf.AddEdge(,node[][i],,node[][i+]);
}
for(int i = ; i < n; i++){///除了源点和汇点,其他拆点
int from = i, to = tot++;
mcmf.AddEdge(from,to,,);
for(int j = ; j < node[i].size(); j+=){
mcmf.AddEdge(to,node[i][j],,node[i][j+]);
}
}
for(int i = ; i < node[n].size(); i+=){
mcmf.AddEdge(n,node[n][i],,node[n][i+]);
}
mcmf.MincostMaxflow(s,t,cost);
printf("%lld\n",cost);
}
return ;
}
UVA1658 Admiral 拆点法解决结点容量(路径不能有公共点,容量为1的时候) 最小费用最大流的更多相关文章
- UVa 1658 - Admiral(最小费用最大流 + 拆点)
链接: https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem& ...
- UVA 1658 海军上将(拆点法+最小费用限制流)
海军上将 紫书P375 这题我觉得有2个难点: 一是拆点,要有足够的想法才能把这题用网络流建模,并且知道如何拆点. 二是最小费用限制流,最小费用最大流我们都会,但如果限制流必须为一个值呢?比如这题限制 ...
- poj3422 拆点法x->x'建立两条边+最小费用最大流
/** 题目:poj3422 拆点法+最小费用最大流 链接:http://poj.org/problem?id=3422 题意:给定n*n的矩阵,含有元素值,初始sum=0.每次从最左上角开始出发,每 ...
- codevs1033 蚯蚓的游戏问题 裸最小费用最大流,注意要拆点
因为蚯蚓走过的路径不能重合,所以把每个点拆成两个点,容量赋为1,保证不会走过相同的点,再加超级源点(程序中为1)和一个辅助点(程序中为2)容量赋为k来控制蚯蚓的数量,最后汇集到一个超级汇点上.做一遍最 ...
- BZOJ-1070 修车 最小费用最大流+拆点+略坑建图
1070: [SCOI2007]修车 Time Limit: 1 Sec Memory Limit: 162 MB Submit: 3624 Solved: 1452 [Submit][Status] ...
- hdu 2686&&hdu 3376(拆点+构图+最小费用最大流)
Matrix Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Subm ...
- UVA - 1658 Admiral (最小费用最大流)
最短路对应费用,路径数量对应流量.为限制点经过次数,拆点为边.跑一次流量为2的最小费用最大流. 最小费用最大流和最大流EK算法是十分相似的,只是把找增广路的部分换成了求费用的最短路. #include ...
- hdu3488 / hdu3435 / hdu1853 最小费用最大流 圈 拆点
题目大意: 在一个有向图中,求经过所有点的最小圈. 思路: (如果是用二分图的完美匹配来做,那么直接上模版就好了).http://www.cnblogs.com/Potato-lover/p/3991 ...
- BZOJ1927: [Sdoi2010]星际竞速(最小费用最大流 最小路径覆盖)
题意 题目链接 Sol 看完题不难想到最小路径覆盖,但是带权的咋做啊?qwqqq 首先冷静思考一下:最小路径覆盖 = \(n - \text{二分图最大匹配数}\) 为什么呢?首先最坏情况下是用\(n ...
随机推荐
- pythonGUI菜单栏和弹出菜单
菜单栏代码: from tkinter import * root = Tk() menubar = Menu(root) def callback(): pass filemenu = Menu(m ...
- linux-更改文件属性-chattr与lsattr
chattr命令的用法:chattr [ -RVf ] [ -v version ] [ mode ] 文件 最关键的是在[mode]部分,[mode]部分是由+-=和[ASacDdIijsTtu]这 ...
- JNI之常用函数大全
要素 :1. 该函数大全是基于C语言方式的,对于C++方式可以直接转换 ,例如,对于生成一个jstring类型的方法转换分别如下: C编程环境中使用方法为:(*env) ->NewString ...
- Go 测试单个方法/性能测试
Go 测试单个方法 gotest.go package mytest import ( "errors" ) func Division(a, b float64) (float6 ...
- CMD一键获取cpu信息
windows + R 输入cmd打开CMD 输入wmic cpu get Name 获取cpu名称-即物理cpu数 cpu get NumberOfCores获取cpu核心数 cpu get Num ...
- [转载]CodeGear RAD 2007 SP4 最新下载及破解
CodeGear RAD 2007 SP4 最新下载及破解 SN: 3AKS-S46LXF-5W7LSF-52CN SN: H4DP-YUSNW7-3MB4TK-2BLD (用这个安装才有源码) C ...
- Python 自用代码(知网会议论文网页源代码清洗)
#coding=utf-8 from pymongo import MongoClient from lxml import etree import requests jigou = u" ...
- Windows 10系统专业精简
第1页:捆绑应用一键卸载 随着微软彻底放弃win7的更新,win8的弱势,新一代的win10系统则成为了微软着力打造的王牌系统. 作为微软最新的王牌产品,win10系统从功能到外观都有着超过前代产品的 ...
- C#文本框中默认是不允许使用全选的
C#文本框中默认是不允许使用全选的.可以通过以下事件完成: private void textBox1_KeyDown(object sender, KeyEventArgs e) { i ...
- 编程算法 - 推断二叉树是不是平衡树 代码(C)
推断二叉树是不平衡树 代码(C) 本文地址: http://blog.csdn.net/caroline_wendy 题目: 输入一颗二叉树的根结点, 推断该树是不是平衡二叉树. 二叉平衡树: 随意结 ...