传送门

模型

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

实现

为了限制经过次数,将每个点i拆成xi,yi.

1、从xi向yi连一条容量为1,费用为1的有向边(1<i<N),

2、从x1向y1连一条容量为2,费用为1的有向边,

3、从xN向yN连一条容量为2,费用为1的有向边,

4、如果存在边(i,j)(i<j)从yi向xj连一条容量为1,费用为0的有向边.

如果存在边(i,j)(i>j),那么交换i,j,再连边,因为原题是过去再回来,我们要转换成网络流的图,只求起点到终点的最大费用流。

如果存在边(i,j)(i==1 && j==n) 那么要连一条容量为2,费用为0的边。

因为原题要求最大费用流,所以我们需要将费用取反,求出费用后再取反回来。

求x1到yN的最大费用最大流.若(x1,y1)满流,则有解,答案为最大费用最大流-2;否则,无解.

分析

每条航线都是自西向东,本题可以转化为求航线图中从1到N两条不相交的路径,使得路径长度之和最大。转化为网络流模型,就是找两条最长的增广路。由于每个城市只能访问一次,要把城市

拆成两个点,之间连接一条容量为1的边,费用设为1。因为要找两条路径,所以起始点和终点内部的边容量要设为2。那么费用流值-2就是两条路径长度之和,为什么减2,因为有两条容量为2

的边多算了1的费用。求最大费用最大流后,如果(<1.a>,<1.b>)不是满流,那么我们找到的路径不够2条(可能是1条,也可能0条),所以无解。

——代码

 #include <map>
#include <queue>
#include <cstdio>
#include <cstring>
#include <iostream>
#define N 10001
#define M 1000001
#define min(x, y) ((x) < (y) ? (x) : (y)) int n, m, cnt, flow, ans, s, t;
std::string str[], s1, s2;
std::map <std::string, int> p;
int head[N], to[M], val[M], cost[M], next[M], dis[N], pre[N];
bool vis[N]; inline void add(int x, int y, int z, int c)
{
to[cnt] = y;
val[cnt] = z;
cost[cnt] = c;
next[cnt] = head[x];
head[x] = cnt++;
} inline bool spfa()
{
int i, u, v;
std::queue <int> q;
memset(vis, , sizeof(vis));
memset(pre, -, sizeof(pre));
memset(dis, / , sizeof(dis));
q.push(s);
dis[s] = ;
while(!q.empty())
{
u = q.front(), q.pop();
vis[u] = ;
for(i = head[u]; i ^ -; i = next[i])
{
v = to[i];
if(val[i] && dis[v] > dis[u] + cost[i])
{
dis[v] = dis[u] + cost[i];
pre[v] = i;
if(!vis[v])
{
q.push(v);
vis[v] = ;
}
}
}
}
return pre[t] ^ -;
} int main()
{
int i, j, d, now;
scanf("%d %d", &n, &m);
s = , t = n << ;
memset(head, -, sizeof(head));
for(i = ; i <= n; i++)
{
std::cin >> str[i];
p[str[i]] = i;
if(i ^ && i ^ n)
add(i, i + n, , -), add(i + n, i, , );
else
add(i, i + n, , -), add(i + n, i, , );
}
for(i = ; i <= m; i++)
{
std::cin >> s1 >> s2;
if(p[s1] > p[s2]) std::swap(s1, s2);
if(p[s1] == && p[s2] == n)
add(p[s1] + n, p[s2], , ), add(p[s2], p[s1] + n, , );
else
add(p[s1] + n, p[s2], , ), add(p[s2], p[s1] + n, , );
}
while(spfa())
{
d = 1e9;
for(i = pre[t]; i ^ -; i = pre[to[i ^ ]]) d = min(d, val[i]);
for(i = pre[t]; i ^ -; i = pre[to[i ^ ]])
{
val[i] -= d;
val[i ^ ] += d;
}
flow += d;
ans += dis[t] * d;
}
if(flow ^ )
{
printf("No Solution!");
return ;
}
printf("%d\n", -ans - );
memset(vis, , sizeof(vis));
vis[] = vis[] = ;
std::cout << str[] << std::endl;
for(i = head[s + n]; i ^ -; i = next[i])
if(!val[i] && !vis[to[i]])
{
now = to[i];
while(!vis[now])
{
vis[now] = ;
std::cout << str[now] << std::endl;
for(j = head[now + n]; j ^ -; j = next[j])
if(!val[j] && !vis[to[j]])
{
now = to[j];
break;
}
}
break;
}
for(i = head[n]; i ^ -; i = next[i])
if(!val[i ^ ] && !vis[to[i] - n])
{
now = to[i] - n;
while(!vis[now])
{
vis[now] = ;
std::cout << str[now] << std::endl;
for(j = head[now]; j ^ -; j = next[j])
if(!val[j ^ ] && !vis[to[j] - n])
{
now = to[j] - n;
break;
}
}
break;
}
std::cout << str[] << std::endl;
return ;
}

[luoguP2770] 航空路线问题(最小费用最大流)的更多相关文章

  1. bzoj 1877 [SDOI2009]晨跑(最小费用最大流)

    Description Elaxia最近迷恋上了空手道,他为自己设定了一套健身计划,比如俯卧撑.仰卧起坐等 等,不过到目前为止,他坚持下来的只有晨跑. 现在给出一张学校附近的地图,这张地图中包含N个十 ...

  2. [BZOJ2055]80人环游世界 有上下界最小费用最大流

    2055: 80人环游世界 Time Limit: 10 Sec  Memory Limit: 64 MB Description     想必大家都看过成龙大哥的<80天环游世界>,里面 ...

  3. BZOJ 1877:[SDOI2009]晨跑(最小费用最大流)

    晨跑DescriptionElaxia最近迷恋上了空手道,他为自己设定了一套健身计划,比如俯卧撑.仰卧起坐等 等,不过到目前为止,他坚持下来的只有晨跑. 现在给出一张学校附近的地图,这张地图中包含N个 ...

  4. BZOJ 2055 80人环游世界 有上下界最小费用可行流

    题意: 现在有这么一个m人的团伙,也想来一次环游世界. 他们打算兵分多路,游遍每一个国家.    因为他们主要分布在东方,所以他们只朝西方进军.设从东方到西方的每一个国家的编号依次为1...N.假若第 ...

  5. [SDOI2009]晨跑[最小费用最大流]

    [SDOI2009]晨跑 最小费用最大流的板子题吧 令 \(i'=i+n\) \(i -> i'\) 建一条流量为1费用为0的边这样就不会对答案有贡献 其次是对 \(m\) 条边建 \(u'-& ...

  6. [板子]最小费用最大流(Dijkstra增广)

    最小费用最大流板子,没有压行.利用重标号让边权非负,用Dijkstra进行增广,在理论和实际上都比SPFA增广快得多.教程略去.转载请随意. #include <cstdio> #incl ...

  7. bzoj1927最小费用最大流

    其实本来打算做最小费用最大流的题目前先来点模板题的,,,结果看到这道题二话不说(之前打太多了)敲了一个dinic,快写完了发现不对 我当时就这表情→   =_=你TM逗我 刚要删突然感觉dinic的模 ...

  8. ACM/ICPC 之 卡卡的矩阵旅行-最小费用最大流(可做模板)(POJ3422)

    将每个点拆分成原点A与伪点B,A->B有两条单向路(邻接表实现时需要建立一条反向的空边,并保证环路费用和为0),一条残留容量为1,费用为本身的负值(便于计算最短路),另一条残留容量+∞,费用为0 ...

  9. HDU5900 QSC and Master(区间DP + 最小费用最大流)

    题目 Source http://acm.hdu.edu.cn/showproblem.php?pid=5900 Description Every school has some legends, ...

  10. P3381 【模板】最小费用最大流

    P3381 [模板]最小费用最大流 题目描述 如题,给出一个网络图,以及其源点和汇点,每条边已知其最大流量和单位流量费用,求出其网络最大流和在最大流情况下的最小费用. 输入输出格式 输入格式: 第一行 ...

随机推荐

  1. UVA 11988 Broken Keyboard (链表)

    简单题,题目要求显然是很多次插入,所以是链表. 插入两个语句,nxt[i] = nxt[u] 表示 i结点指向u的后继, nxt[u] = i表示把u的后继设成i. 设置一个头结点,指向一个不存在的结 ...

  2. webpack安装包的时候 1程序目录不要在C盘 2路径不要有中文 3用cnpm

    webpack安装包的时候 1程序目录不要在C盘 2路径不要有中文 3用cnpm

  3. 2018.4.3 Linux环境变量与变量

    环境变量与变量 shell在开始执行时就已经定义了一些和系统的工作环境有关的变量,用户还可以重新定义这些变量. 环境变量可用命令env或set来查询.(DOS环境为set) 环境变量查询与显示 env ...

  4. CRF条件随机场简介<转>

    转自http://hi.baidu.com/hehehehello/item/3b0d1f8ba1c2e5c698255f89 CRF(Conditional Random Field) 条件随机场是 ...

  5. nfs-ganesha使用

    一 nfs-ganesha在centos7上安装 yum -y install centos-release-gluster yum install -y nfs-ganesha.x86_64yum ...

  6. DROP INDEX - 删除一个索引

    SYNOPSIS DROP INDEX name [, ...] [ CASCADE | RESTRICT ] DESCRIPTION 描述 DROP INDEX 从数据库中删除一个现存的索引. 要执 ...

  7. NIOP 膜你题

    NOIp膜你题   Day1 duliu 出题人:ZAY    1.大美江湖(mzq.cpp/c) [题目背景] 细雪飘落长街,枫叶红透又一年不只为故友流连,其实我也恋长安听门外足音慢,依稀见旧时容颜 ...

  8. JTT808、JTT809、JTT796、JTT794、JTT1077、JTT1078区别与交通部道路运输车辆卫星定位系统部标标准大全下载地址

    部标JT/T808协议.JT/T809协议.JT/T796标准.JT/T794标准的区别,他们是基于不同的通信场景,不同的通信对象,不同的设计目的和目标而制定出来的.首先要知道这些标准的全称是什么意思 ...

  9. c++基本配置属性页

    怎么调试一个项目. 需要配置好环境. 在一个release版本的环境中,调试要用release-debug版本,一般不用debug版本. 配置类型一般不变.

  10. rest_framework之status HTTP状态码

    Django Rest Framework有一个status.py的文件 通常在我们Django视图(views)中,HTTP状态码使用的是纯数字,像400,404,200,304等,并不是那么很好理 ...