2017乌鲁木齐网络赛 J题 Our Journey of Dalian Ends ( 最小费用最大流 )
题意 : 给出一副图,大连是起点,终点是西安,要求你求出从起点到终点且经过中转点上海的最小花费是多少?
分析 :
最短路是最小费用最大流的一个特例,所以有些包含中转限制或者经过点次数有限制的最短路问题都可以考虑使用最小费用最大流来建图解决。
首先对于每个点都只能经过一次这个限制,在网络流中是比较常见的一个限制,只要将所有的点由一拆二且两点间连容量为 1 且花费为 0 的边。
这题的建图很巧妙,是将中转点作为汇点,提示到了这里不如停下来想想如何建图?
然后抽象出一个超级源点,然后将起点和终点与超级源点连一条容量为 1 且 花费为 0 的边,最后将上海这个中转点作为超级汇点。
最后跑出的最小费用最大流就是答案,当然最大流应当是要等于 2 的,如果没有解则说明 MaxFlow < 2。
#include<bits/stdc++.h> using namespace std; ; const int INF = 0x3f3f3f3f; ]; map<string, int> mp; int id; struct Edge { int from,to,cap,flow,cost; Edge(int u,int v,int ca,int f,int co):from(u),to(v),cap(ca),flow(f),cost(co){}; }; struct MCMF { int n,m,s,t; vector<Edge> edges; vector<int> G[maxn]; int inq[maxn];//是否在队列中 int d[maxn];//距离 int p[maxn];//上一条弧 int a[maxn];//可改进量 void init(int n)//初始化 { this->n=n; ;i<=n;i++) G[i].clear(); edges.clear(); } void AddEdge(int from,int to,int cap,int cost)//加边 { edges.push_back(Edge(,cost)); edges.push_back(Edge(to,,,-cost)); int m=edges.size(); G[); G[to].push_back(m-); } bool SPFA(int s,int t,int &flow,int &cost)//寻找最小费用的增广路,使用引用同时修改原flow,cost { ;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]--; ;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]) { inq[e.to]++; Q.push(e.to); } } } } if(d[t]==INF) return false;//汇点不可达则退出 flow+=a[t]; cost+=d[t]*a[t]; int u=t; while(u!=s)//更新正向边和反向边 { edges[p[u]].flow+=a[t]; edges[p[u]^].flow-=a[t]; u=edges[p[u]].from; } return true; } int MincotMaxflow(int s,int t) { ,cost=; while(SPFA(s,t,flow,cost)); return cost; } }MM; inline void init() { mp.clear(); mp[;///中转点上海 mp[;///起点大连 mp[;///终点西安 id = ; } int main(void) { int nCase; cin>>nCase; while(nCase--){ init(); int M; cin>>M; string From, To; int Weight; ; i<=M; i++){ cin>>From>>To>>Weight; if(!mp.count(From)) mp[From] = id++; if(!mp.count(To)) mp[To] = id++; arr[i].from = mp[From]; arr[i].to = mp[To]; arr[i].w = Weight; } ; MM.init(*n+); MM.AddEdge(, , , ); MM.AddEdge(, , , ); ; i<=n; i++) MM.AddEdge(i, i+n, , ); ; i<=M; i++){ MM.AddEdge(arr[i]., arr[i].w); MM.AddEdge(arr[i].to+n, arr[i]., arr[i].w); } printf(, )); } ; }
2017乌鲁木齐网络赛 J题 Our Journey of Dalian Ends ( 最小费用最大流 )的更多相关文章
- 2017乌鲁木齐网络赛 j 题
题目连接 : https://nanti.jisuanke.com/t/A1256 Life is a journey, and the road we travel has twists and t ...
- Our Journey of Dalian Ends && Our Journey of Xian Ends 最小费用最大流
2017 ACM-ICPC 亚洲区(乌鲁木齐赛区)网络赛Our Journey of Dalian Ends 题意:要求先从大连到上海,再从上海打西安,中途会经过其他城市,每个城市只能去一次,出一次, ...
- Libre 6011 「网络流 24 题」运输问题 (网络流,最小费用最大流)
Libre 6011 「网络流 24 题」运输问题 (网络流,最小费用最大流) Description W 公司有m个仓库和n个零售商店.第i个仓库有\(a_i\)个单位的货物:第j个零售商店需要\( ...
- luogu 1327 数列排序 & 2017 ACM-ICPC 亚洲区(南宁赛区)网络赛 J题 循环节
luogu 1327 数列排序 题意 给定一个数列\(\{an\}\),这个数列满足\(ai≠aj(i≠j)\),现在要求你把这个数列从小到大排序,每次允许你交换其中任意一对数,请问最少需要几次交换? ...
- 2013 长沙网络赛J题
思路:这题对于其他能退出所有值的情况比较好像,唯一不能确定的是XXOXXOXXOXX这个形式的序列,其中XX表示未知,O表示已知. 我们令num[1]=0,那么num[4]=sum[3]-sum[2] ...
- 2013 ACM/ICPC 长沙网络赛J题
题意:一个数列,给出这个数列中的某些位置的数,给出所有相邻的三个数字的和,数列头和尾处给出相邻两个数字的和.有若干次询问,每次问某一位置的数字的最大值. 分析:设数列为a1-an.首先通过相邻三个数字 ...
- hihocoder 1236(2015北京网络赛 J题) 分块bitset乱搞题
题目大意: 每个人有五门课成绩,初始给定一部分学生的成绩,然后每次询问给出一个学生的成绩,希望知道在给定的一堆学生的成绩比这个学生每门都低或者相等的人数 因为强行要求在线查询,所以题目要求,每次当前给 ...
- 2017乌鲁木齐区域赛D题Fence Building-平面图的欧拉公式
这个题B站上面有这题很完整的分析和证明,你实在不懂,可以看看这个视频 https://www.bilibili.com/video/av19849697?share_medium=android&a ...
- Sum 南京网络赛J题
题意: 统计每个数的因子的对数,如果因子能被某个平方数整除,则不统计在内,每对因子有序 解析: 我们对某个数n进行质因子分解,如果某个质因子的指数大于2则 f(n) = 0, 例 N = X3 * M ...
随机推荐
- Golang基础(4):Go结构体
当我们要表示同一种数据类型时候,可以用到数组,切片和字典. 当我们要表示不同的数据类型呢?这时候就要用到结构体了 一:定义struct 关键字 type 和 struct 来定义结构体 type st ...
- CSS3——对齐 组合选择符 伪类 伪元素 导航栏 下拉菜单
水平&垂直对齐 元素居中对齐 .center { margin: auto; width: 50%; border: 3px solid green; padding: 10px; } 文本 ...
- C++:补齐函数编写递归函数计算x的y次幂(hhhh函数 !头疼!)
编写递归函数计算x的y次幂,在主程序中输入非零整数x和整数y,输出求幂的结果(保留两位小数).考虑y为负数和0的情况. #include<iostream> #include<iom ...
- lsb-realse
[root@localhost ~]# lsb_release -a -bash: lsb_release: command not found 解决方法:yum install redhat-lsb ...
- OpenCV在ARM-linux上的移植过程遇到的问题3---共享库中嵌套库居然带路径【未解决】
[Linux开发]OpenCV在ARM-linux上的移植过程遇到的问题3-共享库中嵌套库居然带路径[未解决] 标签(空格分隔): [Linux开发] 移植opencv到tq2440 一.下载open ...
- Mysql函数----控制流函数介绍
MySQL有4个函数用来进行条件操作的,可以实现SQL的条件逻辑,允许开发者将一些应用程序业务逻辑转换到数据库后台. MySQL控制流函数: 1.CASE WHEN[test1] THEN [re ...
- C++中的class和struct区别
1,经过不停的改进,结构体 struct 变得原来越不像它在 C 语言中的样子了: 1,struct 在 C 语言中仅为了定义一个变量的集合,仅此而已,不能定义函数: 2,struct 在 C++ 中 ...
- uboot第二阶段分析1
一. uboot第二阶段初识 1.1. uboot第二阶段应该做什么 a. 概括来讲uboot第一阶段主要就是初始化了SoC内部的一些部件(譬如看门狗.时钟),然后初始化DDR并且完成重定位. b. ...
- offsetWidth clientWidth scrollWidth 的区别
了解 offsetWidth clientWidth scrollWidth 的区别 最近需要清除区分开元素的width,height及相应的坐标等,当前这篇用来区分offsetWidth clien ...
- 如何查看Win10开机运行了多长时间 - Windows10.Pro
原文:如何查看Win10开机运行了多长时间 - Windows10.Pro 方法一:使用Windows PowerShell命令查看 以管理员身份运行Windows PowerShell,在打开的“管 ...