您的位置:首页 > 理论基础 > 计算机网络

LG2770/LOJ6122 航空路线问题 费用流 网络流24题

2019-09-20 22:00 10 查看
原文链接:http://www.cnblogs.com/liubainian/p/11560060.html

问题描述

LG2770

LOG6122

题解

教训:关掉流同步之后就不要用其他输入输出方式了。

拆点。

两个拆点之间连\((1,1)\),其他连\((1,0)\)

\(\mathrm{Code}\)

#include<bits/stdc++.h>
using namespace std;

void read(int &x){
x=0;char ch=1;int fh;
while(ch!='-'&&(ch>'9'||ch<'0')) ch=getchar();
if(ch=='-') ch=getchar(),fh=-1;
else fh=1;
while(ch>='0'&&ch<='9') x=(x<<1)+(x<<3)+ch-'0',ch=getchar();
x*=fh;
}

const int maxn=203;
const int maxm=1000003;

const int INF=0x3f3f3f3f;
int flag;
int n,m;
map<string,int>mp;
string s[maxn],s1,s2;

int Head[maxn],Next[maxm],to[maxm],w[maxm],co[maxm],tot=1;
int S,T,maxflow,ans;

void add(int x,int y,int flow,int cost){
to[++tot]=y,Next[tot]=Head[x],Head[x]=tot,w[tot]=flow,co[tot]=cost;
}

int dis[maxn],pre[maxm],now[maxn];
bool vis[maxn];

void dfs1(int x){
cout<<s[x]<<endl;
vis[x]=1;
for(int i=Head[x];i;i=Next[i]){
int y=to[i];
if(y>n&&y<=2*n&&w[i]==0){
dfs1(y-n);break;
}
}
}

void dfs2(int x){
vis[x]=1;
for(int i=Head[x];i;i=Next[i]){
int y=to[i];
if(y>n&&y<=2*n&&w[i]==0&&!vis[y-n]){
dfs2(y-n);break;
}
}
cout<<s[x]<<endl;
}

bool spfa(){
memset(dis,0xcf,sizeof(dis)),memset(vis,0,sizeof(vis));memset(pre,0,sizeof(pre));
now[S]=INF;queue<int>q;q.push(S);vis[S]=1;dis[S]=0;
while(!q.empty()){
int x=q.front();vis[x]=0;q.pop();
for(int i=Head[x];i;i=Next[i]){
int y=to[i],len=w[i],cost=co[i];
if(!len||dis[y]>=dis[x]+cost) continue;
dis[y]=dis[x]+cost,now[y]=min(now[x],len);
pre[y]=i;
if(!vis[y]){q.push(y);vis[y]=1;}
}
}
return dis[T]!=(int)0xcfcfcfcf;
}

void upd(){
maxflow+=now[T],ans+=dis[T]*now[T];
int p=T;
while(p!=S){
int k=pre

; w[k]-=now[T],w[k xor 1]+=now[T]; p=to[k xor 1]; } } int main(){ ios::sync_with_stdio(0); cin>>n>>m; for(int i=1;i<=n;i++){ cin>>s[i];mp[s[i]]=i; } S=n*2+1,T=S+1; add(S,n+1,INF,0);add(n+1,S,0,0); add(n,T,INF,0);add(T,n,0,0); for(int i=1;i<=n;i++){ if(i!=1&&i!=n) add(i+n,i,1,1),add(i,i+n,0,-1); else add(i+n,i,2,1),add(i,i+n,0,-1); } for(int i=1;i<=m;i++){ cin>>s1;cin>>s2; int x=mp[s1],y=mp[s2]; if(x>y) swap(x,y); if(x==1&&y==n) flag=1; add(x,y+n,1,0),add(y+n,x,0,0); } while(spfa()) upd(); if(maxflow==2) cout<<ans-2<<endl; else if(maxflow==1&&flag){ cout<<2<<endl;cout<<s[1]<<endl<<s <<endl<<s[1]<<endl;return 0; } else{ cout<<"No Solution!"<<endl;return 0; } memset(vis,0,sizeof(vis)); dfs1(1);dfs2(1); return 0; }

[/code] [p]转载于:https://www.cnblogs.com/liubainian/p/11560060.html

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: