Loading [MathJax]/jax/output/CommonHTML/config.js
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >洛谷P2770 航空路线问题(费用流)

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

作者头像
attack
发布于 2018-07-27 07:28:55
发布于 2018-07-27 07:28:55
36900
代码可运行
举报
运行总次数:0
代码可运行

题意

$n$个点从左向右依次排列,有$m$条双向道路

问从起点到终点,再从终点回到起点,在经过的点不同的情况下最多能经过几个点

Sol

首先,问题可以转化为求两条互不相交的路径,使得点数最多

为了满足流量的限制,肯定会想到拆点,把每个点拆为两个,连流量为$1$,费用为$1$的边

起点和终点连费用为1,流量为2的边

输出方案比较蛋疼,我是dfs两次,然后第二次倒着输出

但是$a->c->a$这种情况会WA,so只好打表喽

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<queue>
#include<map>
#include<iostream>
using namespace std;
const int MAXN = 1e4 + 10, INF = 1e9 + 10;
inline int read() {
    char c = getchar(); int x = 0, f = 1;
    while(c < '0' || c > '9') {if(c == '-') f = 1; c = getchar();}
    while(c >= '0' && c <= '9') x = x * 10 + c - '0', c = getchar();
    return x * f;
}
int N, M, S, T;
map<string, int> ID;
map<int, string> nam;
int flag[MAXN];
struct Edge {
    int u, v, w, f, nxt, vi;
}E[MAXN];
int head[MAXN], num = 0;
inline void add_edge(int x, int y, int w, int f) {
    E[num] = (Edge) {x, y, -w, f, head[x], 0};
    head[x] = num++;
}
inline void AddEdge(int x, int y, int w, int f) {
    add_edge(x, y, w, f); add_edge(y, x, -w, 0);
}
int dis[MAXN], vis[MAXN], Pre[MAXN];
bool SPFA() {
    memset(dis, 0x3f, sizeof(dis));
    memset(vis, 0, sizeof(vis));
    queue<int> q; q.push(S); dis[S] = 0;
    while(!q.empty()) {
        int p = q.front(); q.pop(); vis[p] = 0;
        for(int i = head[p]; i != -1; i = E[i].nxt) {
            int to = E[i].v;
            if(E[i].f && dis[to] > dis[p] + E[i].w) {
                dis[to] = dis[p] + E[i].w; Pre[to] = i;
                if(!vis[to]) vis[to] = 1, q.push(to);
            }
        }
    }
    return dis[T] <= INF;
}
int F() {
    int flow = INF;
    for(int i = T; i != S; i = E[Pre[i]].u) flow = min(flow, E[Pre[i]].f);
    for(int i = T; i != S; i = E[Pre[i]].u) E[Pre[i]].f -= flow, E[Pre[i] ^ 1].f += flow;
    return flow * dis[T];
}
int MCMF() {
    int ans = 0;
    while(SPFA()) ans += F();
    return ans;
}
int out[3][MAXN], tot[3];
void dfs(int now, int opt) {
    if(vis[now] || now == N) return ;
    vis[now] = 1;
    for(int i = head[now]; i != -1; i = E[i].nxt) {
        int to = E[i].v;
        if((E[i].u <= N && E[i].v >= N && (E[i].u + N != to)) || (to > N && to - N < out[opt][tot[opt]])) continue;
        if(!vis[to] && E[i].f < 1) {
            E[i].vi = 1;
            if(to == E[i].u + N) out[opt][++tot[opt]] = E[i].u;
            dfs(E[i].v, opt);
        }
    }
}
int main() {
    memset(head, -1, sizeof(head));
    N = read(); M = read(); S = 1; T = N + N;
    for(int i = 1; i <= N; i++) {
        string s; cin >> s; ID[s] = i; nam[i] = s;
        AddEdge(i, i + N, 1, (i == 1 || i == N) ? 2 : 1);
    }
    for(int i = 1; i <= M; i++) {
        string a, b; cin >> a >> b;
        if(ID[a] > ID[b]) swap(a, b);
        AddEdge(ID[a] + N, ID[b], 0, 1);
    }
    int ans = -MCMF() - 2;
    if(ans <= -2) {puts("No Solution!"); return 0;}
    if(ans == 0) {
        printf("2\n");
        cout << nam[1] << endl;
        cout << nam[N] << endl;
        cout << nam[1] << endl;
        return 0;
    }
    printf("%d\n", ans);
    memset(vis, 0, sizeof(vis)); dfs(1, 1);
    memset(vis, 0, sizeof(vis)); 
    for(int i = 1; i <= tot[1]; i++) vis[out[1][i]] = 1; vis[1] = 0;
    dfs(1, 2);
    for(int i = 1; i <= tot[1]; i++) 
        cout << nam[out[1][i]] << endl;
    cout << nam[N] << endl;
    for(int i = tot[2]; i >= 1; i--) 
        cout << nam[out[2][i]] << endl;
    return 0;
}
/*

*/
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2018-07-23 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
洛谷P3358 最长k可重区间集问题(费用流)
题目描述 对于给定的开区间集合 I 和正整数 k,计算开区间集合 I 的最长 k可重区间集的长度。 输入输出格式 输入格式: 的第 1 行有 2 个正整数 n和 k,分别表示开区间的个数和开区
attack
2018/04/10
8800
洛谷P3358 最长k可重区间集问题(费用流)
洛谷P4014 分配问题(费用流)
题目描述 有 nn 件工作要分配给 nn 个人做。第 ii 个人做第 jj 件工作产生的效益为 c_{ij}cij​ 。试设计一个将 nn 件工作分配给 nn 个人做的分配方案,使产生的总效益最大。 输入输出格式 输入格式: 文件的第 11 行有 11 个正整数 nn ,表示有 nn 件工作要分配给 nn 个人做。 接下来的 nn 行中,每行有 nn 个整数 c_{ij}cij​ ​​,表示第 ii 个人做第 jj 件工作产生的效益为 c_{ij}cij​ 。 输出格式: 两行分别输出最小总效益和最大总效益
attack
2018/04/10
7510
洛谷P4013 数字梯形问题(费用流)
梯形的第一行有 mmm 个数字。从梯形的顶部的 mmm 个数字开始,在每个数字处可以沿左下或右下方向移动,形成一条从梯形的顶至底的路径。
attack
2018/07/27
3380
洛谷P4013 数字梯形问题(费用流)
洛谷P3356 火星探险问题(费用流)
题目描述 火星探险队的登陆舱将在火星表面着陆,登陆舱内有多部障碍物探测车。登陆舱着陆后,探测车将离开登陆舱向先期到达的传送器方向移动。探测车在移动中还必须采集岩石标本。每一块岩石标本由最先遇到它的探测车完成采集。每块岩石标本只能被采集一次。岩石标本被采集后,其他探测车可以从原来岩石标本所在处通过。探测车不能通过有障碍的地面。本题限定探测车只能从登陆处沿着向南或向东的方向朝传送器移动,而且多个探测车可以在同一时间占据同一位置。如果某个探测车在到达传送器以前不能继续前进,则该车所采集的岩石标本将全部损失。 用一
attack
2018/04/10
6800
洛谷P3357 最长k可重线段集问题(费用流)
题目描述http://www.cnblogs.com/zwfymqz/p/8559566.html 给定平面 x-O-yx−O−y 上 nn 个开线段组成的集合 II ,和一个正整数 kk 。试设计一个算法,从开线段集合 II 中选取出开线段集合 S\subseteq IS⊆I ,使得在 xx 轴上的任何一点 pp ,SS 中与直线 x=px=p 相交的开线段个数不超过 kk ,且\sum\limits_{z\in S}|z|z∈S∑​∣z∣ 达到最大。这样的集合 SS 称为开线段集合 II 的最长 kk 
attack
2018/04/10
8660
洛谷P4015 运输问题(费用流)
题目描述 WW 公司有 mm 个仓库和 nn 个零售商店。第 ii 个仓库有 a_iai​ 个单位的货物;第 jj 个零售商店需要 b_jbj​ 个单位的货物。 货物供需平衡,即\sum\limits_{i=1}^{m}a_i=\sum\limits_{j=1}^{n}b_ji=1∑m​ai​=j=1∑n​bj​ 。 从第 ii 个仓库运送每单位货物到第 jj 个零售商店的费用为 c_{ij}cij​ ​​ 。 试设计一个将仓库中所有货物运送到零售商店的运输方案,使总运输费用最少。 输入输出格式 输入格式:
attack
2018/04/10
8040
洛谷P4016 负载平衡问题(最小费用最大流)
题目描述 GG 公司有 nn 个沿铁路运输线环形排列的仓库,每个仓库存储的货物数量不等。如何用最少搬运量可以使 nn 个仓库的库存数量相同。搬运货物时,只能在相邻的仓库之间搬运。 输入输出格式 输入格式: 文件的第 11 行中有 11 个正整数 nn ,表示有 nn 个仓库。 第 22 行中有 nn 个正整数,表示 nn 个仓库的库存量。 输出格式: 输出最少搬运量。 输入输出样例 输入样例#1:  5 17 9 14 16 4 输出样例#1:  11 说明 1 \leq n \leq 1001≤n≤10
attack
2018/04/10
8260
洛谷P4012 深海机器人问题(费用流)
题目描述 深海资源考察探险队的潜艇将到达深海的海底进行科学考察。 潜艇内有多个深海机器人。潜艇到达深海海底后,深海机器人将离开潜艇向预定目标移动。 深海机器人在移动中还必须沿途采集海底生物标本。沿途生物标本由最先遇到它的深海机器人完成采集。 每条预定路径上的生物标本的价值是已知的,而且生物标本只能被采集一次。 本题限定深海机器人只能从其出发位置沿着向北或向东的方向移动,而且多个深海机器人可以在同一时间占据同一位置。 用一个 P\times QP×Q 网格表示深海机器人的可移动位置。西南角的坐标为 (0,0)
attack
2018/04/10
6600
洛谷P4012 深海机器人问题(费用流)
洛谷P1251 餐巾计划问题(最小费用最大流)
从$S$向$i'$连边$(p, INF)$,表示每天早上可以以$p$的费用无限提供餐巾
attack
2018/08/01
3770
BZOJ4514: [Sdoi2016]数字配对(费用流)
Description 有 n 种数字,第 i 种数字是 ai、有 bi 个,权值是 ci。 若两个数字 ai、aj 满足,ai 是 aj 的倍数,且 ai/aj 是一个质数, 那么这两个数字可以配对,并获得 ci×cj 的价值。 一个数字只能参与一次配对,可以不参与配对。 在获得的价值总和不小于 0 的前提下,求最多进行多少次配对。 Input 第一行一个整数 n。 第二行 n 个整数 a1、a2、……、an。 第三行 n 个整数 b1、b2、……、bn。 第四行 n 个整数 c1、c2、……、cn。 O
attack
2018/04/03
1.2K0
洛谷P2045 方格取数加强版(费用流)
对于拆出来的每个点,在其中连两条边,一条为费用为点权,流量为1,另一条费用为0,流量为INF
attack
2019/03/05
3690
洛谷P3381 【模板】最小费用最大流(dijstra费用流)
题目描述 如题,给出一个网络图,以及其源点和汇点,每条边已知其最大流量和单位流量费用,求出其网络最大流和在最大流情况下的最小费用。 输入输出格式 输入格式: 第一行包含四个正整数N、M、S、T,分别表示点的个数、有向边的个数、源点序号、汇点序号。 接下来M行每行包含四个正整数ui、vi、wi、fi,表示第i条有向边从ui出发,到达vi,边权为wi(即该边最大流量为wi),单位流量的费用为fi。 输出格式: 一行,包含两个整数,依次为最大流量和在最大流量情况下的最小费用。 输入输出样例 输入样例#1: 4
attack
2018/04/10
2.3K0
洛谷P3381 【模板】最小费用最大流(dijstra费用流)
BZOJ 1179: [Apio2009]Atm(tarjan+SPFA)
Description Siruseri 城中的道路都是单向的。不同的道路由路口连接。按照法律的规定, 在每个路口都设立了一个 Siruser i 银行的 ATM 取款机。令人奇怪的是,Siruseri 的酒吧也都设在路口,虽然并不是每个路口都设有酒吧。Bandit ji 计划实施 Siruseri 有史以来最惊天动地的 ATM 抢劫。他将从市中心 出发,沿着单向道路行驶,抢劫所有他 途径的 ATM 机,最终他将在一个酒吧庆 祝他的胜利。使用高超的黑客技术,他获知了每个 ATM 机中可以掠取的 现金数额。他
attack
2018/04/10
7810
BZOJ 1179: [Apio2009]Atm(tarjan+SPFA)
BZOJ4819: [Sdoi2017]新生舞会(01分数规划)
Description 学校组织了一次新生舞会,Cathy作为经验丰富的老学姐,负责为同学们安排舞伴。有n个男生和n个女生参加舞会 买一个男生和一个女生一起跳舞,互为舞伴。Cathy收集了这些同学之间的关系,比如两个人之前认识没计算得出  a[i][j] ,表示第i个男生和第j个女生一起跳舞时他们的喜悦程度。Cathy还需要考虑两个人一起跳舞是否方便, 比如身高体重差别会不会太大,计算得出 b[i][j],表示第i个男生和第j个女生一起跳舞时的不协调程度。当然, 还需要考虑很多其他问题。Cathy想先用一个
attack
2018/04/10
7520
洛谷P3355 骑士共存问题
题目描述 在一个 n*n个方格的国际象棋棋盘上,马(骑士)可以攻击的棋盘方格如图所示。棋盘上某些方格设置了障碍,骑士不得进入 对于给定的 n*n 个方格的国际象棋棋盘和障碍标志,计算棋盘上最多可以放置
attack
2018/04/11
9370
洛谷P3355 骑士共存问题
洛谷P2891 [USACO07OPEN]吃饭Dining
题目描述 Cows are such finicky eaters. Each cow has a preference for certain foods and drinks, and she will consume no others. Farmer John has cooked fabulous meals for his cows, but he forgot to check his menu against their preferences. Although he might not
attack
2018/04/11
8110
洛谷P2891 [USACO07OPEN]吃饭Dining
洛谷P4174 [NOI2006]最大获利
题目描述 新的技术正冲击着手机通讯市场,对于各大运营商来说,这既是机遇,更是挑战。THU 集团旗下的 CS&T 通讯公司在新一代通讯技术血战的前夜,需要做太多的准备工作,仅就站址选择一项,就需要完成前期市场研究、站址勘测、最优化等项目。 在前期市场调查和站址勘测之后,公司得到了一共 N 个可以作为通讯信号中转站的地址,而由于这些地址的地理位置差异,在不同的地方建造通讯中转站需要投入的成本也是不一样的,所幸在前期调查之后这些都是已知数据:建立第 i个通讯中转站需要的成本为  (1≤i≤N)。 另外公司调查得
attack
2018/04/11
7050
LOJ#505. 「LibreOJ β Round」ZQC 的游戏(最大流)
题意 题目链接 Sol 首先把第一个人能吃掉的食物删掉 然后对每个人预处理出能吃到的食物,直接限流跑最大流就行了 判断一下最后的最大流是否等于重量和 注意一个非常恶心的地方是需要把除1外所有人都吃不到的食物删掉 #include<bits/stdc++.h> using namespace std; const int MAXN = 1e6 + 10, INF = 1e9 + 10; int sqr(int x) {return x * x;} inline int read() { char c
attack
2019/02/26
4280
cf1051F. The Shortest Statement(最短路)
由于边数的限制,非树边连接的点不会超过$2*(m - (n - 1)) = 42$个
attack
2018/09/30
4030
loj#2312. 「HAOI2017」八纵八横(线性基 线段树分治)
题意 题目链接 Sol 线性基+线段树分治板子题。。 调起来有点自闭。。 #include<bits/stdc++.h> #define fi first #define se second #define pb push_back #define bit bitset<B + 1> using namespace std; const int MAXN = 501, B = 1001, SS = 4001; inline int read() { char c = getchar(); i
attack
2019/04/01
5780
相关推荐
洛谷P3358 最长k可重区间集问题(费用流)
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验