题目链接 \(Click\) \(Here\)

本来想调剂心情没想到写了那么久,还被\(dreagonm\)神仙嘲讽不会传纸条,我真是太弱了\(QAQ\)(原因:最开始写最大费用最大流一直想消圈,最后发现自己完全是\(zz\)了)

这个题是最大费用最大流,避免正环的关键在于只从西向东连边。还有要注意题目中并没有说能任一点开始结束,所以必须是两条\(1->n\)的路线。

路径输出方法真的是学到了,看下面代码吧。还有注意只有\(1->n\)一条边的特判。

#include <bits/stdc++.h>
using namespace std; const int N = 400010;
const int M = 4000010;
const int INF = 0x3f3f3f3f; int cnt = -1, head[N]; struct edge {
int nxt, to, f, w;
}e[M]; void add_edge (int from, int to, int flw, int val) {
e[++cnt].nxt = head[from];
e[cnt].to = to;
e[cnt].f = flw;
e[cnt].w = val;
head[from] = cnt;
} void add_len (int u, int v, int f, int w) {
add_edge (u, v, f, +w);
add_edge (v, u, 0, -w);
} int n, m; map <string, int> mp; string s1, s2, str[110]; int inn (int x) {return n * 0 + x;}
int out (int x) {return n * 1 + x;} queue <int> q;
int vis[N], dis[N], flow[N];
int pre_edge[N], pre_node[N], max_flow, max_cost; bool spfa (int s, int t) {
memset (vis, 0, sizeof (vis));
memset (dis, -0x3f, sizeof (dis));
memset (flow, 0x3f, sizeof (flow));
dis[s] = 0; vis[s] = true; q.push (s);
while (!q.empty ()) {
int u = q.front (); q.pop ();
for (int i = head[u]; ~i; i = e[i].nxt) {
int v = e[i].to;
if (dis[v] < dis[u] + e[i].w && e[i].f) {
dis[v] = dis[u] + e[i].w;
flow[v] = min (flow[u], e[i].f);
pre_edge[v] = i;
pre_node[v] = u;
if (!vis[v]) {
vis[v] = true;
q.push (v);
}
}
}
vis[u] = false;
}
return dis[t] != dis[0];
} void dfs1 (int x) {
cout << str[x - n] << endl;//第一遍dfs正序输出
vis[x] = 1;//不让第二次dfs再找到这个点
for (int i = head[x]; ~i; i = e[i].nxt) {
if (e[i].to <= n && !e[i].f) {
dfs1 (e[i].to + n);
break;
}//第一次dfs只找一条路径,找到就break
}
} void dfs2 (int x) {
vis[x - n] = 1;
for (int i = head[x]; ~i; i = e[i].nxt) {
if (e[i].to <= n && !e[i].f && !vis[e[i].to + n]) {
dfs2 (e[i].to + n);
}//不走第一次路径走过的点
}
cout << str[x - n] << endl;//第二次dfs倒序输出
}//vis[n]在第一次dfs已经设为1,不会输出第二次 int main () {
memset (head, -1, sizeof (head));
cin >> n >> m;
int s = n * 2 + 1;
int t = n * 2 + 2;
for (int i = 1; i <= n; ++i) {
cin >> str[i]; mp[str[i]] = i;
add_len (inn (i), out (i), 1, 1);
}
add_len (inn (1), out (1), 1, 0);
add_len (inn (n), out (n), 1, 0);
add_len (s, inn (1), 2, 0);
add_len (out (n), t, 2, 0);
bool have = false;
for (int i = 1; i <= m; ++i) {
cin >> s1 >> s2;
if (mp[s1] > mp[s2]) swap (s1, s2);
have |= (mp[s1] == 1 && mp[s2] == n);
add_len (out (mp[s1]), inn (mp[s2]), 1, 0);
}
max_flow = 0, max_cost = 0;
while (spfa (s, t)) {
max_flow += flow[t];
max_cost += dis[t] * flow[t];
int u = t;
while (u != s) {
e[pre_edge[u] ^ 0].f -= flow[t];
e[pre_edge[u] ^ 1].f += flow[t];
u = pre_node[u];
}
}
if (max_flow == 1 && have) {
cout << max_cost << endl;
cout << str[1] << endl << str[n] << endl << str[1] << endl;
} else if (max_flow == 2){
memset (vis, 0, sizeof (vis));
cout << max_cost << endl;
dfs1 (n + 1); dfs2 (n + 1);
} else puts ("No Solution!");
}

Luogu P2770 航空路线问题的更多相关文章

  1. 网络流 P2770 航空路线问题

    #include <cstdio> #include <cstdlib> #include <map> #include <queue> #includ ...

  2. P2770 航空路线问题

    \(\color{#0066ff}{题目描述}\) 给定一张航空图,图中顶点代表城市,边代表 2 城市间的直通航线.现要求找出一条满足下述限制条件的且途经城市最多的旅行路线. (1)从最西端城市出发, ...

  3. 洛谷P2770 航空路线问题(费用流)

    传送门 完了这题好厉害……字符串什么的好麻烦…… 要求从$1$到$n$的路径,不重复,经过边数最多 每一个点拆成两个,$A_i,B_i$,然后$A_i$到$B_i$连容量为$1$,费用为$1$的边,保 ...

  4. 洛谷P2770 航空路线问题(费用流)

    题意 $n$个点从左向右依次排列,有$m$条双向道路 问从起点到终点,再从终点回到起点,在经过的点不同的情况下最多能经过几个点 Sol 首先,问题可以转化为求两条互不相交的路径,使得点数最多 为了满足 ...

  5. 洛谷 P2770 航空路线问题【最大费用最大流】

    记得cnt=1!!因为是无向图所以可以把回来的路看成另一条向东的路.字符串用map处理即可.拆点限制流量,除了1和n是(i,i+n,2)表示可以经过两次,其他点都拆成(i,i+n,1),费用设为1,原 ...

  6. 洛谷P2770 航空路线问题 最小费用流

    Code: #include<cstdio> #include<iostream> #include<algorithm> #include<vector&g ...

  7. 【题解】【网络流24题】航空路线问题 [P2770] [Loj6122]

    [题解][网络流24题]航空路线问题 [P2770] [Loj6122] 传送门:航空路线问题 \([P2770]\) \([Loj6122]\) [题目描述] 给出一张有向图,每个点(除了起点 \( ...

  8. JS前端三维地球渲染——中国各城市航空路线展示

    前言 我还从来没有写过有关纯JS的文章(上次的矢量瓦片展示除外,相对较简单.),自己也学习过JS.CSS等前端知识,了解JQuery.React等框架,但是自己艺术天分实在不过关,不太喜欢前端设计,比 ...

  9. loj #6122. 「网络流 24 题」航空路线问题

    #6122. 「网络流 24 题」航空路线问题 题目描述 给定一张航空图,图中顶点代表城市,边代表两个城市间的直通航线.现要求找出一条满足下述限制条件的且途经城市最多的旅行路线. 从最西端城市出发,单 ...

随机推荐

  1. Mayor's posters(线段树+离散化)

    这道题最关键的点就在离散化吧. 假如有三张海报[1, 10] [10, 13][15,  20] 仅仅三个区间就得占用到20了. 但是离散化后就可以是[1, 2] [2, 3] [4, 5] n到1e ...

  2. UVA 12171 Sculpture

    https://vjudge.net/problem/UVA-12171 题目 某人设计雕塑,用的是很扯的方法:把一堆长方体拼起来.给出长方体的坐标和长宽高,求外表面积.因为要将这雕塑进行酸洗,需要知 ...

  3. PlaNet,使用图像输入来学习世界模型

    Google AI团队与DeepMind合作,上周宣布了一个名为PlaNet的新的开源“Deep Planning”网络. PlaNet是一个人工智能代理,它只使用图像输入来学习世界模型,并使用这些模 ...

  4. 解决vscode egg调试出现: this socket has been ended by other party【转】

    如果是最新的1.22 方案一 回退版本到1.21.1 https://code.visualstudio.com/updates/v1_21 方案二 退而求其次, 更改debug配置, 待官方或egg ...

  5. Spring MVC 使用介绍(三)—— Controller接口控制器

    一.概述 Controller接口类图如下,其中,BaseCommandController已从Spring 4移除 基于继承Controller接口的方式已经不推荐使用,仅供学习参考 二.基于Con ...

  6. mysql 0x80004005 unable to connect to any of the specified mysql hosts

    语言:c# 问题:偶尔会出现连不上mysql 报标题的这个错误. 解决方法:把server = localhost 改为 =127.0.0.1 或者静态IP  ,按着改暂时没出现了,继续观望!

  7. AWS免费EC2

    终于弄到这个EC2了.回想下过程大概如下 1.注册账号 https://amazonaws-china.com/cn/free/ 可以这地址点击"创建免费账户" 2.注册填写信息, ...

  8. LVS-Keepalived高可用集群(NAT)

    LEA-6-LVS-NAT+Keepalived高可用集群-------client-----------------主LVS-----------------从LVS---------------- ...

  9. noiac64 sort (二分答案)

    首先如果L=1,那就可以直接用一个优先队列来做 但它并不是1 所以要换个做法 假设我们已经知道第L的数是x,第R的数是y 那其实就只需要找到[x+1,y+1]这一段,然后再加上一定数量的x和y就是答案 ...

  10. ACM-ICPC 2017 Asia Xi'an A XOR (线性基+线段树思想)

    题目链接 题意;给个数组,每次询问一个区间你可以挑任意个数的数字异或和 然后在或上k的最大值 题解:线性基不知道的先看这个,一个线性基可以log的求最大值把对应去区间的线性基求出来然后用线段树维护线性 ...