题目链接 \(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. Vue之变量、数据绑定、事件绑定使用举例

    vue1.html <!DOCTYPE html> <html lang="en" xmlns:v-bind="http://www.w3.org/19 ...

  2. 【python练习题】程序14

    #题目:将一个正整数分解质因数.例如:输入90,打印出90=2*3*3*5. #我的方法应该比网上的更加简洁,只是递归可能速度慢 n = input('请输入一个正整数:') n = int(n) X ...

  3. css中绝对定位和相对定位详解

    相对定位relative和绝对定位absolute 相对定位 相对定位是标签在根据没加position样式前的位置来定位不会受父级标签的定位的影响,并且定位后不会脱离文本流,会占据原来的位置. 接下来 ...

  4. kubernetes Helm-chart web UI添加

    charts web ui 添加chart仓库 helm repo add cherryleo https://fileserver-1253732882.cos.ap-chongqing.myqcl ...

  5. 51Nod 1344 走格子

    参考自:https://www.cnblogs.com/ECJTUACM-873284962/p/6445381.html 1344 走格子 基准时间限制:1 秒 空间限制:131072 KB 分值: ...

  6. Elasticsearch 删除数据

    删除数据分为两种:一种是删除索引(数据和表结构同时删除,作用同SQLSERVER 中 DROP TABLE "表格名" ),另一种是删除数据(不删除表结构,作用同SQLSERVER ...

  7. M - 约会安排 HDU - 4553 线段树 (最长连续段)

    中文题面 思路:维和两个区间  一个是女神区间 一个是基友区间  如果是基友要预约时间 直接在基友区间查询可满足的起点 (这里先判tree[1].m >=length也就是有没有这样的区间满足时 ...

  8. Pearls POJ - 1260 dp

    题意:有n种不同的珍珠 每种珍珠的价格不同  现在给出一个采购单 标注了需要不同等级的珍珠和相对于的个数(输入按价格升序排列) 其中 价格为   (当前种类价格+10)*购买数量  这样就有一种诡异的 ...

  9. Codeforces986E Prince's Problem 【虚树】【可持久化线段树】【树状数组】

    我很喜欢这道题. 题目大意: 给出一棵带点权树.对每个询问$ u,v,x $,求$\prod_{i \in P(u,v)}gcd(ai,x)$.其中$ P(u,v) $表示$ u $到$ v $的路径 ...

  10. [PA2012] Tax

    传送门:>Here< 题意:给出一个N个点M条边的无向图,经过一个点的代价是进入和离开这个点的两条边的边权的较大值,求从起点1到点N的最小代价.起点的代价是离开起点的边的边权,终点的代价是 ...