洛谷P2770 航空路线问题 最小费用流
水题.
本质上题目要求的是一个包含 $1$,$n$ 的最大环,所以每个点只可以经过一次.
那么就拆点,然后限制每个点的经过次数就行了.
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<vector>
#include<cstring>
#include<queue>
#include<string>
#include<map>
using namespace std;
const int maxn=800;
const int INF=1000000+23666;
typedef long long ll;
map<string,int>idx;
string A[maxn];
int viss[maxn];
int s,t,n;
struct Edge{
int from,to,cap,cost;
Edge(int u,int v,int c,int f):from(u),to(v),cap(c),cost(f){}
};
vector<Edge>edges;
vector<int>G[maxn];
struct MCMF{
int d[maxn],inq[maxn],a[maxn],flow2[maxn];
queue<int>Q;
ll ans=0;
int flow=0;
void addedge(int u,int v,int c,int f){
edges.push_back(Edge(u,v,c,f)); //正向弧
edges.push_back(Edge(v,u,0,-f)); //反向弧
int m=edges.size();
G[u].push_back(m-2);
G[v].push_back(m-1);
}
int SPFA(){
for(int i=0;i<=n;++i)d[i]=INF,flow2[i]=INF;
memset(inq,0,sizeof(inq));int f=INF;
d[s]=0,inq[s]=1;Q.push(s);
while(!Q.empty()){
int u=Q.front();Q.pop();inq[u]=0;
int sz=G[u].size();
for(int i=0;i<sz;++i){
Edge e=edges[G[u][i]];
if(e.cap>0&&d[e.to]>d[u]+e.cost){
a[e.to]=G[u][i];
d[e.to]=d[u]+e.cost;
flow2[e.to]=min(flow2[u],e.cap);
if(!inq[e.to]){inq[e.to]=1;Q.push(e.to);}
}
}
}
if(d[t]==INF)return 0;
f=flow2[t];
flow+=f;
int u=edges[a[t]].from;
edges[a[t]].cap-=f;
edges[a[t]^1].cap+=f;
while(u!=s){
edges[a[u]].cap-=f;
edges[a[u]^1].cap+=f;
u=edges[a[u]].from;
}
ans+=(ll)(d[t]*f);
return 1;
}
int maxflow(){
while(SPFA());
return flow;
}
ll getcost(){return ans;}
}op;
void print(int x){
if(x==t-1)return;
int sz=G[x+1].size();
for(int i=0;i<sz;++i){
int e=G[x+1][i];
if(e%2==0&&edges[e].cap==0&&!viss[e]){
print(edges[e].to);
cout<<A[x]<<endl;
return;
}
}
}
int main(){
int N,M;cin>>N>>M;
int cnt=1;
for(int i=1;i<=N;++i){
string s;cin>>s;idx[s]=cnt;A[cnt]=s;
if(i==1||i==N)op.addedge(cnt,cnt+1,2,0);
else op.addedge(cnt,cnt+1,1,0);
cnt+=2;
}
n=cnt-1,s=1,t=n;
for(int i=1;i<=M;++i)
{
string a,b;cin>>a>>b;
int ax=idx[a],bx=idx[b];
if(ax<bx)op.addedge(ax+1,bx,1,-1);
else op.addedge(bx+1,ax,1,-1);
}
int F=op.maxflow();
ll ans=op.getcost();
if(F!=2)
{
if(ans==-1){
cout<<2<<endl;
cout<<A[s]<<endl;
cout<<A[t-1]<<endl;
cout<<A[s]<<endl;
return 0;
}
else {cout<<"No Solution!"<<endl;return 0;}
}
cout<<-ans<<endl;
int tr=s;
cout<<A[s]<<endl;
do
{
++tr;
int sz=G[tr].size();
for(int i=0;i<sz;++i){
int e=G[tr][i];
if(e%2==0&&edges[e].cap==0){tr=edges[e].to,viss[e]=1;break;}
}
if(tr!=t)cout<<A[tr]<<endl;
}while(tr!=t);
print(s);
return 0;
}
洛谷P2770 航空路线问题 最小费用流的更多相关文章
- 洛谷P2770 航空路线问题(费用流)
传送门 完了这题好厉害……字符串什么的好麻烦…… 要求从$1$到$n$的路径,不重复,经过边数最多 每一个点拆成两个,$A_i,B_i$,然后$A_i$到$B_i$连容量为$1$,费用为$1$的边,保 ...
- 洛谷P2770 航空路线问题(费用流)
题意 $n$个点从左向右依次排列,有$m$条双向道路 问从起点到终点,再从终点回到起点,在经过的点不同的情况下最多能经过几个点 Sol 首先,问题可以转化为求两条互不相交的路径,使得点数最多 为了满足 ...
- 洛谷 P2770 航空路线问题【最大费用最大流】
记得cnt=1!!因为是无向图所以可以把回来的路看成另一条向东的路.字符串用map处理即可.拆点限制流量,除了1和n是(i,i+n,2)表示可以经过两次,其他点都拆成(i,i+n,1),费用设为1,原 ...
- [洛谷1649]障碍路线<BFS>
题目链接:https://www.luogu.org/problem/show?pid=1649 历经千辛万苦,我总算是把这个水题AC了,现在心里总觉得一万只草泥马在奔腾: 这是一道很明显的BFS,然 ...
- 网络流 P2770 航空路线问题
#include <cstdio> #include <cstdlib> #include <map> #include <queue> #includ ...
- P2770 航空路线问题
\(\color{#0066ff}{题目描述}\) 给定一张航空图,图中顶点代表城市,边代表 2 城市间的直通航线.现要求找出一条满足下述限制条件的且途经城市最多的旅行路线. (1)从最西端城市出发, ...
- Luogu P2770 航空路线问题
题目链接 \(Click\) \(Here\) 本来想调剂心情没想到写了那么久,还被\(dreagonm\)神仙嘲讽不会传纸条,我真是太弱了\(QAQ\)(原因:最开始写最大费用最大流一直想消圈,最后 ...
- 洛谷P2770 双路DP // 网络流
https://www.luogu.org/problemnew/show/P2770 第一眼看过去,觉得这不是一个经典的双路DP模型吗,将一条过去一条回来互不相交的路径看作是起点出发了两条路径一起走 ...
- 洛谷 P4201 设计路线 [NOI2008] 树形dp
正解:树形dp 解题报告: 大概是第一道NOI的题目?有点激动嘻嘻 然后先放个传送门 先大概港下这题的题意是啥qwq 大概就是给一棵树,然后可以选若干条链把链上的所有边的边权变成0,但是这些链不能有交 ...
随机推荐
- WebApi笔记
WebApi有一段时间没用了,这几天用webapi做了一个接口供第三方调用,又重新折腾了下,做个笔记记录下心得,防止遗忘. 1.webapi使用的RESTful风格的传参方式,其实就是充分利用HTTP ...
- Prototype-based programming
Prototype-based programming is a style of object-oriented programming in which behaviour reuse (know ...
- nginx上搭建https
nginx上配置https的条件: 1.SSL证书和服务器私钥文件 2.nginx支持SSL模块 一.获取SSL证书 网上有提供权威认证的SSL证书的网站,但多数是收费的,而且不便宜.在正式的生产环境 ...
- Kattis - bela
Bela Young Mirko is a smart, but mischievous boy who often wanders around parks looking for new idea ...
- 一个helloword hibernate配置以及查询
搭建一个Hibernate环境,开发步骤: 1. 下载源码 版本:hibernate-distribution-3.6.0.Final 2. 引入jar文件 hibernate3.jar核心 + ...
- APICloud资料
//语音读text里面的文字 var text=document.getElementById('ready').value; alert(text); var obj = api.require(' ...
- vue 页面跳转及参数传递和接收
跳转: this.$router.push({name: 'My',params:{ id:'1',name:'anson'}}); 接收: {{this.$route.params.id}}
- SPOJ CIRU
SPOJ CIRU 题意 给出n个圆,求他们覆盖的面积. 解法 自适应Simpson,但需要将圆离散化一下,以保证我们查询的是一个连续的有圆的区间. 奇怪的是我没有离散化,样例都没有过,却把题给A了 ...
- python_三级字典
data = { "北京":{ "昌平":{ "沙河":["oldboy","test"], &qu ...
- [luogu] P4364 [九省联考2018]IIIDX(贪心)
P4364 [九省联考2018]IIIDX 题目背景 Osu 听过没?那是Konano 最喜欢的一款音乐游戏,而他的梦想就是有一天自己也能做个独特酷炫的音乐游戏.现在,他在世界知名游戏公司KONMAI ...