洛谷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,但是这些链不能有交 ...
随机推荐
- soapUI检查webServices接口的方法以及对自动触发线程的查询
这几天需要熟悉接口传输过来的数据,因此会用到soapUI,但是没结果这个工具,然后百度了下,结合了下,下面是我对webservice在soapUI的展现: 1:其实说白了,就是我们不知道从接口里传输过 ...
- MongoDB_安装
windows安装MongoDB 官网下载地址:https://www.mongodb.com/download-center?jmp=nav#community (1)如图点击DOWNLOAD进行下 ...
- NotFoundHttpException
报错:NotFoundHttpException 这种一般都是路由配置错误
- JS数据分组[JSON]
JS 数据分组 var arr = [{ "id": "1001", "name": "值1", "value ...
- IT同行请教我如何培养读书习惯,结果就是“读了1本书,并写下'读《成交》有感'一文”
前段时间,我把CSDN博客的签名加上了"读过100+本经典书籍". 一个经常关注我CSDN博客的老乡,问我是如何做到的. 该老乡,准确来说是前辈,该前辈买了很多技术读物却没有耐心读 ...
- UVALIVE 4256 Salesmen
Salesmen Time Limit: 3000ms Memory Limit: 131072KB This problem will be judged on UVALive. Original ...
- ASP.NET-常用正则表达式
常用正则表达式 正则: [RegularExpression(@"[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+.[A-Za-z]{2,4}", ErrorMes ...
- 电子签章盖章之jQuery插件jquery.zsign
简介: 使用jquery.zsign可以实现电子签章盖章效果,使用方便,只需提供自己的章图片.效果图如下: 页面引用: <link href=&quo ...
- HDU 4332 Contest 4
顶好的一道题.其实,是POJ 2411的升级版.但POJ 2411我用的插头DP来做,一时没想到那道题怎么用状态DP,于是回头看POJ 2411那一道的状态DP,其实也很简单,就是每一行都设一个状态, ...
- POJ 2183
模拟题 #include <iostream> #include <cstdio> #include <algorithm> using namespace std ...