博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
网络流24题-飞行员配对方案问题
阅读量:4636 次
发布时间:2019-06-09

本文共 3124 字,大约阅读时间需要 10 分钟。

飞行员配对方案问题

时空限制1000ms / 128MB

题目背景

第二次世界大战时期..

题目描述

英国皇家空军从沦陷国征募了大量外籍飞行员。由皇家空军派出的每一架飞机都需要配备在航行技能和语言上能互相配合的2 名飞行员,其中1 名是英国飞行员,另1名是外籍飞行员。在众多的飞行员中,每一名外籍飞行员都可以与其他若干名英国飞行员很好地配合。如何选择配对飞行的飞行员才能使一次派出最多的飞机。对于给定的外籍飞行员与英国飞行员的配合情况,试设计一个算法找出最佳飞行员配对方案,使皇家空军一次能派出最多的飞机。

对于给定的外籍飞行员与英国飞行员的配合情况,编程找出一个最佳飞行员配对方案,使皇家空军一次能派出最多的飞机。

输入输出格式

输入格式:

 

第 1 行有 2 个正整数 m 和 n。n 是皇家空军的飞行员总数(n<100);m 是外籍飞行员数(m<=n)。外籍飞行员编号为 1~m;英国飞行员编号为 m+1~n。

接下来每行有 2 个正整数 i 和 j,表示外籍飞行员 i 可以和英国飞行员 j 配合。最后以 2个-1 结束。

 

输出格式:

 

第 1 行是最佳飞行员配对方案一次能派出的最多的飞机数 M。接下来 M 行是最佳飞行员配对方案。每行有 2个正整数 i 和 j,表示在最佳飞行员配对方案中,飞行员 i 和飞行员 j 配对。如果所求的最佳飞行员配对方案不存在,则输出‘No Solution!’。

 

输入输出样例

输入样例:
5 101 71 82 62 92 103 73 84 74 85 10-1 -1
输出样例: 
41 72 93 85 10

最大流。我选择了拆点,其实仔细想想发现拆不拆点都是一样的。 还有一点需要特别特别注意的是判断两点之间是否有流,可以通过判断它的逆向边是否有流来实现。
#include 
using namespace std;const long long INF=LLONG_MAX/2;const int maxn=257;int now_edge=0,S,T;vector
edge[maxn];int dis[maxn],current[maxn];int fl[maxn][maxn]={
0};struct ss{ int v; long long flow;}edg[maxn*maxn];void addedge(int u,int v,long long flow){ fl[u][v]+=flow; edge[u].push_back(now_edge); edg[now_edge++]=(ss){v,flow}; edge[v].push_back(now_edge); edg[now_edge++]=(ss){u,0};}bool bfs(){ queue
q; q.push(S); memset(dis,0,sizeof(dis)); dis[S]=1; while(!q.empty()) { int now=q.front(); q.pop(); int Size=edge[now].size(); for(int i=0;i
0&&dis[to]==0) { dis[to]=dis[now]+1; q.push(to); } } } if(dis[T]==0)return false; return true;}long long dfs(int now,long long maxflow){ if(now==T)return maxflow; int Size=edge[now].size(); for(int i=current[now];i
0) { long long flow=dfs(e.v,min(maxflow,e.flow)); if(flow!=0) { fl[now][e.v]-=flow; fl[e.v][now]+=flow; e.flow-=flow; edg[edge[now][i]^1].flow+=flow; return flow; } } } return 0;}long long dinic(){ long long ans=0; while(bfs()) { long long flow; memset(current,0,sizeof(current)); while(bool(flow=dfs(S,INF)))ans+=flow; } return ans;}int main(){ int m,n,a,b; scanf("%d %d",&m,&n); while(scanf("%d %d",&a,&b)==2) { if(a==-1)break; addedge(a*2,b*2-1,1); } for(int i=1;i<=n;i++)addedge(2*i-1,2*i,1); S=2*n+1; T=2*n+2; for(int i=1;i<=m;i++)addedge(S,i*2-1,1); for(int i=m+1;i<=n;i++)addedge(i*2,T,1); long long ans=dinic(); if(ans==0)printf("No Solution!\n"); else { printf("%lld\n",ans); for(int i=1;i<=m;i++) for(int j=m+1;j<=n;j++) if(fl[j*2-1][i*2]) { printf("%d %d\n",i,j); break; } } return 0;}
View Code

 

转载于:https://www.cnblogs.com/tian-luo/p/9507801.html

你可能感兴趣的文章
Android JSON、GSON、FastJson的封装与解析
查看>>
Luogu P1340 兽径管理
查看>>
pip install 问题
查看>>
Vagrant 入门 - 配置
查看>>
Luogu P1315 观光公交
查看>>
vue-router导航守卫,限制页面访问权限
查看>>
UNDERSTANDING CALLBACK FUNCTIONS IN JAVASCRIPT
查看>>
玩法详细说明文档
查看>>
Archlinux GNOME 3 操作习惯的变更
查看>>
visual studio 2005 常用按键
查看>>
2019 Multi-University Training Contest 1 - 1012 - NTT
查看>>
谭浩强C程序设计(第四版)例题中的代码优化
查看>>
浏览器调试淘宝首页看到有趣的招聘信息
查看>>
ASP.NET Identity “角色-权限”管理 4
查看>>
[转][译]ASP.NET MVC 4 移动特性
查看>>
SOC CPU
查看>>
get_result --perl
查看>>
163镜像地址
查看>>
ehcache memcache redis 三大缓存男高音
查看>>
eclipse 快捷键Open Implementation 直接退出
查看>>