【问题分析】

求最长两条不相交路径,用最大费用最大流解决。

【建模方法】

把第i个城市拆分成两个顶点<i.a>,<i.b>。

1、对于每个城市i,连接(<i.a>,<i.b>)一条容量为1,费用为1的有向边,特殊地(<1.a>,<1.b>)和(<N.a>,<N.b>)容量设为2。
2、如果城市i,j(j>i)之间有航线,从<i.b>到<j.a>连接一条容量为1,费用为0的有向边。

求源<1.a>到汇<N.b>的最大费用最大流。如果(<1.a>,<1.b>)不是满流,那么无解。否则存在解,即为最大费用最大流量 - 2。

【建模分析】

每条航线都是自西向东,本题可以转化为求航线图中从1到N两条不相交的路径,使得路径长度之和最大。转化为网络流模型,就是找两条最长的增广路。由于每个城市只能访问一次,要把城市拆成两个点,之间连接一条容量为1的边,费用设为1。因为要找两条路径,所以起始点和终点内部的边容量要设为2。那么费用流值-2就是两条路径长度之和,为什么减2,因为有两条容量为2的边多算了1的费用。求最大费用最大流后,如果(<1.a>,<1.b>)不是满流,那么我们找到的路径不够2条(可能是1条,也可能0条),所以无解。

【问题另解】

经典的多线程动态规划问题。

#include<cstdio>
#include<algorithm>
#include<cstring>
#include<iostream>
#include<queue>
#include<map>
using namespace std;
typedef long long ll;
const int N = 500007, M = 500007, INF = 0x3f3f3f3f;namespace dinic{const int N = 500007, M = 500007, INF = 0x3f3f3f3f;const ll LINF = 0x3f3f3f3f3f;int S, T, n;int head[N], nex[M], ver[M], tot, cur[N];ll dist[N], edge[M], cost[M], maxflow, mincost;bool vis[N];inline void add(int x, int y, ll z, ll c, bool o = 1){ver[tot] = y;edge[tot] = z;cost[tot] = c;nex[tot] = head[x];head[x] = tot ++ ;if(o)add(y, x, 0, -c, 0);}inline bool spfa(){for(int i = 1; i <= n; ++ i)dist[i] =LINF;memset(vis, 0, sizeof vis);queue<int>q;q.push(S);dist[S] = 0;vis[S] = 1;while(q.size()){int x = q.front();q.pop();vis[x] = 0;for(int  i = head[x]; ~i ;i = nex[i]){int y = ver[i];ll z = edge[i], c = cost[i];if(dist[y] > dist[x] + z && z){dist[y] = dist[x] + z;if(!vis[y])q.push(y), vis[y] = 1;}}}return dist[T] != LINF;}ll dfs(int x, ll flow = LINF){if(x == T)return flow;ll ans = 0, k, i;vis[x] = 1;for(int i = cur[x]; ~i; i = nex[i]){int y = ver[i];ll z = edge[i], c = cost[i];if(z && dist[y] == dist[x] + c && vis[y]){k = dfs(y, min(z, flow));if(!k)dist[y] = LINF;edge[i] -= k;edge[i ^ 1] += k;ans += k, mincost += k * c, flow -= k;}vis[x] = 0;return ans;}}inline void main(){while(spfa()){for(int i = 1; i <= n; ++ i)cur[i] = head[i];ll now;while((now = dfs(S)))maxflow += now;}}inline void init(int _n, int _S, int _T){n = _n, S = _S, T = _T, tot = 0, maxflow = 0, mincost = 0;memset(head, -1, sizeof head);}
}
map<string, int>ip;
bool way[N];
string s[N], ch;
int n, m, S, T;
int x, y;inline void dfs1(int x){way[x] = 1;cout <<s[x - n] << endl;for(int i = dinic::head[x]; ~i; i = dinic::nex[i]){int y = dinic::ver[i], z = dinic::edge[i];if(y <= n && z){dfs1(y + n);break;}}
}inline void dfs2(int x){for(int i = dinic::head[x]; ~i; i = dinic::nex[i]){int y = dinic::ver[i], z = dinic::edge[i];if(y <= n && z && !way[y + n])dfs2(y + n);}cout << s[x - n] << endl;
}int main(){scanf("%d%d", &n, &m);S = 1, T = n << 1;bool flag = 0;dinic::init(n + n + n, S, T);for(int i = 1; i <= n; ++ i)cin >> s[i], ip[s[i]] = i;//i ~ n 表示入点 n + 1 ~ 2 * n 表示出点for(int i = 2; i < n; ++ i)dinic::add(i, n + i, 1, 1);cout << "ok" << endl;dinic::add(1, n + 1, 2, 1), dinic::add(n, n + n, 2, 1);while(m -- ){cin >> ch, x = ip[ch];cin >> ch, y = ip[ch];if(x > y)swap(x, y);flag |= (x == 1 && y == n);dinic::add(x + n, y, 1, 0);}cout << "ok" << endl;dinic:main();cout << "ok" << endl;if(dinic::maxflow == 2)printf("%d", dinic::mincost - 2);else if(dinic::maxflow == 1 && flag){printf("2\n");cout << s[1] << endl << s[n] <<endl << s[1] << endl;return 0;}else return !printf("No Solution!\n");for(int i = 1;  i <= n + 2; ++ i)way[i + n] = 0;dfs1(1 + n), dfs2(1 + n);
}

【网络流24题】解题报告:K、航空路线问题(最小费用最大流)相关推荐

  1. [网络流24题] 最长k可重区间集

    对于区间 u->v ,连接边 u->v,权值为-len,容量为1,之后对每个点 i->i+1,连边 i->i+1,容量为k,权值为0,求区间最左端点到最右端点的费用流,费用相反 ...

  2. 【网络流24题】【LOJ6010】数字梯形(费用流)

    problem 给定一个n行的数字梯形,第一行有m个数字 从第一行的每个数字开始往左下或右下移动到底,累加路径上的值 求数字总和最大. 满足限制: 1.路径互不相交 2.路径仅在数字结点处相交 3.路 ...

  3. [网络流24题][COGS396]魔术球问题简化版(最小割)

    题目描述 传送门 注意题目描述:保证答案小于2000并非1600! 题解 有向无环图的最小路径覆盖问题,转化成最小割问题. 最小路径覆盖数随球的数量递增不递减,满足单调性,所以可以枚举答案(或二分答案 ...

  4. 洛谷 - P2770 航空路线问题(最大费用最大流+路径打印)

    题目链接:点击查看 题目大意:给出一个由n个点及m条边组成的无向图,现在要求从点1出发,到达点n,再回到点1,一路上经过尽可能多的点,并且保证除了起点和终点外的每个点至多只能经过一次,并输出路径 题目 ...

  5. 解题报告:线性规划与网络流24题

    目录 A.飞行员配对方案问题 (二分图最大匹配)(最大流)[提高+/省选- ] B.太空飞行计划问题(最大权闭合图转最小割.最小割方案输出)[省选/NOI- ] C.最小路径覆盖问题(有向无环图最小路 ...

  6. [线性规划与网络流24题] 网络流常见模型

    最近两个月在做<线性规划与网络流24题>这套题,加深了对网络流的理解. 涵盖到的模型有:二分图匹配.二分图的最大独立集.最大权闭合图.有向无环图的最小路径覆盖.最多不相交路径.最大权不相交 ...

  7. 网络流 24 题汇总(LOJ 上只有 22 题???)

    太裸的我就不放代码了...(黑体字序号的题表示值得注意) 1.搭配飞行员 [LOJ#6000] 二分图最大匹配. 2.太空飞行计划 [LOJ#6001] 最小割常规套路.输出方案.(注:这题换行符要用 ...

  8. 【网络流24题】魔术球问题

    [题目]#6003. 「网络流 24 题」魔术球 [算法]最小路径覆盖(详细知识参考网络流总结) [题解](i+j)为完全平方数则连边,那么问题转化为添加尽可能多的点使得最小路径覆盖≤n(一条简单路径 ...

  9. 网络流----最小费用最大流(EK+SPFA)

    先来介绍一下什么是费用流(部分内容参考bilibili董晓算法) 给定一个网络G=(V,E),每条边有容量限制w(u,v),还有单位流量的费用c(u,v). 当(u,v)的流量为f(u,v)时,需要花 ...

  10. 网络流20+4题解题报告(已更前20题)

    链接:网络流20+4题解题报告 代码预览:Github 转载于:https://www.cnblogs.com/water-mi/p/10538858.html

最新文章

  1. 深入讨论.NET Socket的Accept方法
  2. Objective-c 实用代码
  3. Scala Actor并发编程入门示例
  4. 数学好的男生适合学计算机吗,数学好的男生适合读什么专业 2021前景好吗
  5. Android窗口View层次
  6. 个人空间风格模版php,home.php这个页面风格模板在哪里修改?答案:space_home.html...
  7. 一文快速入门分库分表(必修课)
  8. HTML中的父选择器,html – css4中是否有父选择器?
  9. Android 广告内容结合,Android Headlines大盘点:2018华为广告“创新高”
  10. 服务器是什么?本机服务器的查询。
  11. java 运行scala_使用java命令运行scala代码
  12. 24个希腊字母(符号) 附字母表
  13. html中点重置和提交没反应,网页点提交按钮没反应 js提交表单,点击按钮无反应...
  14. wampserver显示红色、橙色的解决方案
  15. win10无法访问xp计算机,WinXP无法访问Win10共享文件夹,拒绝访问怎么办?
  16. 技术寡头争霸传之:控制开源工具,就控制了整个生态
  17. USB host 与 OTG 怎么切换
  18. LAMP环境搭建之编译安装指南(php-5.3.27.tar.gz)
  19. 2020年非上海生源应届普通高校毕业生落户材料办理流程及注意事项
  20. 使用友盟社会化分享IOS版SDK分享纯图片到微信

热门文章

  1. Pytorch中的5个非常有用的张量操作
  2. Altium Designer笔记2
  3. 如何解决diff: /../Podfile.lock: No such file or directory 的问题
  4. WdatePicker 日历控件的onchange事件无作用
  5. java中的NAN和INFINITY
  6. Cacti的库表结构-Data
  7. 我和我的Android
  8. 让烦恼走开 两招让移动硬盘插拔自如
  9. elasticsearch date格式问题
  10. java与工业相机,OpenCV软件与工业相机的组合在机器视觉中的应用