【网络流24题】航空线路问题(费用流)

【网络流24题】航空线路问题(费用流)

题面

Cogs数据有误,提供洛谷题面

题解

这题和原来做过的一道题周游加拿大是一模一样的
所以,这题DP+记录方案应该也是可行的

来考虑网络流的做法
现在的来回,被看成是去两次
所以流量被限定死了,为2
因此要考虑费用流来求解。

每个点只能经过一次
很显然先拆点
如果一个城市被访问了
那么,他的两个点直接的流量是一定存在的
为了记录下这个点被访问过
所以,给定它一个费用1

然后其他的连边和原来做的题目没有什么区别
对于每一条航线,从\(i'\)向\(j\)连边,强制方向,流量为1,容量为INF

现在跑一边最大费用最大流就行了
说白点就是费用全部取负然后跑最小流

输出方案比较诡异
直接看代码。。

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<set>
#include<map>
#include<vector>
#include<queue>
using namespace std;
#define MAX 5000
#define MAXL 500000
#define INF 1000000000
inline int read()
{
    int x=0,t=1;char ch=getchar();
    while((ch<'0'||ch>'9')&&ch!='-')ch=getchar();
    if(ch=='-')t=-1,ch=getchar();
    while(ch<='9'&&ch>='0')x=x*10+ch-48,ch=getchar();
    return x*t;
}
struct Line
{
    int v,next,w,fy;
}e[MAXL];
int h[MAX],cnt=2;
inline void Add(int u,int v,int w,int fy)
{
    e[cnt]=(Line){v,h[u],w,fy};h[u]=cnt++;
    e[cnt]=(Line){u,h[v],0,-fy};h[v]=cnt++;
}
int pe[MAX],pr[MAX],dis[MAX];
bool vis[MAX];
int S,T,Cost,n,m,Flow;
bool SPFA()
{
    memset(dis,63,sizeof(dis));
    queue<int> Q;
    Q.push(S);dis[S]=0;
    while(!Q.empty())
    {
        int u=Q.front();Q.pop();
        for(int i=h[u];i;i=e[i].next)
        {
            int v=e[i].v;
            if(e[i].w&&dis[v]>dis[u]+e[i].fy)
            {
                dis[v]=dis[u]+e[i].fy;
                pe[v]=i;pr[v]=u;
                if(!vis[v])vis[v]=true,Q.push(v);
            }
        }
        vis[u]=false;
    }
    if(dis[T]>=INF)return false;
    int flow=INF;
    for(int i=T;i!=S;i=pr[i])flow=min(flow,e[pe[i]].w);
    for(int i=T;i!=S;i=pr[i])e[pe[i]].w-=flow,e[pe[i]^1].w+=flow;
    Cost-=flow*dis[T];
    Flow+=flow;
    return true;
}
string name[MAX];
map<string,int> M;
vector<int> ans;
void output(int u)
{
    ans.push_back(u);
    if(u==n)return;
    for(int i=h[u+n];i;i=e[i].next)
        if(!vis[i]&&e[i^1].w){vis[i]=true;output(e[i].v);return;}
}
int main()
{
    cin>>n>>m;
    S=0;T=n+n+1;
    for(int i=1;i<=n;++i){cin>>name[i];M[name[i]]=i;}
    for(int i=1;i<=m;++i)
    {
        string s1,s2;
        cin>>s1>>s2;
        int u=M[s1],v=M[s2];
        if(u>v)swap(u,v);
        Add(u+n,v,INF,0);
    }
    Add(S,1,2,0);Add(1,1+n,2,0);
    Add(n+n,T,2,0);Add(n,n+n,INF,0);
    for(int i=2;i<n;++i)Add(i,i+n,1,-1);
    while(SPFA());
    if(Flow!=2){puts("No Solution!");return 0;}
    printf("%d\n",Cost+2);
    bool fl=false;
    output(1);
    for(int i=0;i<ans.size();++i)cout<<name[ans[i]]<<endl;
    ans.clear();output(1);
    for(int i=ans.size()-1;i>=0;--i)if(ans[i]!=n)cout<<name[ans[i]]<<endl;
    return 0;
}

原文地址:https://www.cnblogs.com/cjyyb/p/8186159.html

时间: 2024-10-25 21:13:11

【网络流24题】航空线路问题(费用流)的相关文章

【网络流24题】运输问题(费用流)(网络费用流量)

[网络流24题]运输问题 2014年3月7日1,6360 题目描述 Description W 公司有m个仓库和n 个零售商店.第i 个仓库有ai 个单位的货物:第j 个零售商店需要bj个单位的货物.货物供需平衡,即  sum(si)=sum(bj).从第i 个仓库运送每单位货物到第j 个零售商店的费用为cij .试设计一个将仓库中所有货物运送到零售商店的运输方案,使总运输费用最少.编程任务:对于给定的m 个仓库和n 个零售商店间运送货物的费用,计算最优运输方案和最差运输方案. 输入描述 Inp

[网络流24题] 餐巾计划问题 [费用流]

题面: https://www.luogu.org/problemnew/show/P1251 思路: 这道题乍一看,可以跑上下界费用流 代码量.难度 -> inf 其实不然,我们可以用费用流的特殊处理去掉下界 观察题目,每天要求有ri块餐巾 首先,有贪心如下: 当且仅当每天可供使用的餐巾正好满足需求时,可以有最小费用 证明:若某一天有多一块餐巾,则其根本来源一定是买多了,而且在这块餐巾参与的周转中还消费了一些清洗费用,同时它造成其余的日子里也会有餐巾被闲置 因此首先把题目转化为"每天正好

CGOS461 [网络流24题] 餐巾(最小费用最大流)

题目这么说的: 一个餐厅在相继的N天里,第i天需要Ri块餐巾(i=l,2,…,N).餐厅可以从三种途径获得餐巾. 购买新的餐巾,每块需p分: 把用过的餐巾送到快洗部,洗一块需m天,费用需f分(f<p).如m=l时,第一天送到快洗部的餐巾第二天就可以使用了,送慢洗的情况也如此. 把餐巾送到慢洗部,洗一块需n天(n>m),费用需s分(s<f). 在每天结束时,餐厅必须决定多少块用过的餐巾送到快洗部,多少块送慢洗部.在每天开始时,餐厅必须决定是否购买新餐巾及多少,使洗好的和新购的餐巾之和满足当

网络流24题-航空路线问题

航空路线问题 时空限制1000ms / 128MB 题目描述 给定一张航空图,图中顶点代表城市,边代表 2 城市间的直通航线.现要求找出一条满足下述限制条件的且途经城市最多的旅行路线. (1)从最西端城市出发,单向从西向东途经若干城市到达最东端城市,然后再单向从东向西飞回起点(可途经若干城市). (2)除起点城市外,任何城市只能访问 1 次. 对于给定的航空图,试设计一个算法找出一条满足要求的最佳航空旅行路线. 输入输出格式 输入格式: 第 1 行有 2 个正整数 N 和 V,N 表示城市数,N

LiberOJ #6013. 「网络流 24 题」负载平衡 最小费用最大流 供应平衡问题

#6013. 「网络流 24 题」负载平衡 内存限制:256 MiB时间限制:1000 ms标准输入输出 题目类型:传统评测方式:文本比较 上传者: 匿名 提交提交记录统计讨论测试数据 题目描述 G 公司有 n nn 个沿铁路运输线环形排列的仓库,每个仓库存储的货物数量不等.如何用最少搬运量可以使 n nn 个仓库的库存数量相同.搬运货物时,只能在相邻的仓库之间搬运. 输入格式 文件的第 1 11 行中有 1 11 个正整数 n nn,表示有 n nn 个仓库.第 2 22 行中有 n nn 个

【费用流】【网络流24题】【cogs 739】运输问题

739. [网络流24题] 运输问题 ★★ 输入文件:tran.in 输出文件:tran.out 简单对比 时间限制:1 s 内存限制:128 MB ?问题描述: ?编程任务: 对于给定的m 个仓库和n 个零售商店间运送货物的费用,计算最优运输方案和最差运输方案. ?数据输入: ?结果输出: 程序运行结束时,将计算出的最少运输费用和最多运输费用输出到文件tran.out中. 输入文件示例 输出文件示例 tran.in 2 3 220 280 170 120 210 77 39 105 150 1

【网络流24题】餐巾计划问题(最小费用最大流)

[网络流24题]餐巾计划问题(最小费用最大流) 题面 COGS 洛谷上的数据范围更大,而且要开longlong 题解 餐巾的来源分为两种: ①新买的 ②旧的拿去洗 所以,两种情况分别建图 先考虑第一种 因为新买餐巾没有任何限制,并且随时可以买 所以直接从源点向每一天连边,容量为INF,费用为餐巾的价格 因为流要流出去,所以每个点向汇点连边,容量为每天的用量,费用为0 第二种,旧的拿去洗 首先考虑一下怎么算有多少旧的餐巾 每天用旧的餐巾的数量值一定的,不可能变多 因此从源点向这些点连边,容量为每天

网络流(费用流):[网络流24题] 餐巾

[网络流24题] 餐巾 [问题描述] 一个餐厅在相继的N天里,第i天需要Ri块餐巾(i=l,2,…,N).餐厅可以从三种途径获得餐巾. (1)购买新的餐巾,每块需p分: (2)把用过的餐巾送到快洗部,洗一块需m天,费用需f分(f<p).如m=l时,第一天送到快洗部的餐巾第二天就可以使用了,送慢洗的情况也如此. (3)把餐巾送到慢洗部,洗一块需n天(n>m),费用需s分(s<f). 在每天结束时,餐厅必须决定多少块用过的餐巾送到快洗部,多少块送慢洗部.在每天开始时,餐厅必须决定是否购买新餐

【网络流24题】分配问题(二分图最佳匹配)(费用流)

[网络流24题]分配问题 2014年3月11日1,8720 题目描述 Description 有n件工作要分配给n个人做.第i 个人做第j 件工作产生的效益为ij c .试设计一个将n件工作分配给n个人做的分配方案,使产生的总效益最大.«编程任务:对于给定的n件工作和n个人,计算最优分配方案和最差分配方案. 输入描述 Input Description 第1 行有1 个正整数n,表示有n件工作要分配给n 个人做.接下来的n 行中,每行有n 个整数 cij ,1≤i≤n,1≤j≤n,表示第i 个人