【洛谷 - P2756】飞行员配对方案问题(网络流最大流,输出方案)
題干:
題目背景
第二次世界大戰時期..
題目描述
英國皇家空軍從淪陷國征募了大量外籍飛行員。由皇家空軍派出的每一架飛機都需要配備在航行技能和語言上能互相配合的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!’。
?
輸入輸出樣例
輸入樣例#1:?復制
5 10 1 7 1 8 2 6 2 9 2 10 3 7 3 8 4 7 4 8 5 10 -1 -1輸出樣例#1:?復制
4 1 7 2 9 3 8 5 10題目大意:
? 給一個二分圖,求最大匹配并且輸出方案。
解題報告:
? 直接網絡流建圖,注意邊上的流量都是1,然后輸出方案的時候就看每個左側頂點連出的邊是否流量是0就可以了。流量是0說明有流量流過,也就是匹配了這一對點。
題目描述的邊的流量設為inf也可以,但是這樣判斷的時候就是要判斷反邊的流量是否不為0.
AC代碼:
#include<cstdio> #include<iostream> #include<algorithm> #include<queue> #include<map> #include<vector> #include<set> #include<string> #include<cmath> #include<cstring> #define F first #define S second #define ll long long #define pb push_back #define pm make_pair using namespace std; typedef pair<int,int> PII; const int MAX = 2e5 + 5; int n,m; int tot; struct Edge {int to,ne,w; } e[100005 * 2]; int head[10005]; int st,ed; int dis[10050],q[10005];//一共多少個點跑bfs,dis數組和q數組就開多大。 void add(int u,int v,int w) {e[++tot].to=v;e[tot].w=w;e[tot].ne=head[u];head[u]=tot; } bool bfs(int st,int ed) {memset(dis,-1,sizeof(dis));int front=0,tail=0;q[tail++]=st;dis[st]=0;while(front<tail) {int cur = q[front];if(cur == ed) return 1;front++;for(int i = head[cur]; i!=-1; i = e[i].ne) {if(e[i].w&&dis[e[i].to]<0) {q[tail++]=e[i].to;dis[e[i].to]=dis[cur]+1;}}}if(dis[ed]==-1) return 0;return 1; } int dfs(int cur,int limit) {//limit為源點到這個點的路徑上的最小邊權 if(limit==0||cur==ed) return limit;int w,flow=0;for(int i = head[cur]; i!=-1; i = e[i].ne) { if(e[i].w&&dis[e[i].to]==dis[cur]+1) {w=dfs(e[i].to,min(limit,e[i].w));e[i].w-=w;e[i^1].w+=w;flow+=w;limit-=w;if(limit==0) break;}}if(!flow) dis[cur]=-1;return flow; } int dinic() {int ans = 0;while(bfs(st,ed)) ans+=dfs(st,0x7fffffff);return ans; } int main() {cin>>m>>n;st=0;ed=n+1;tot=1;for(int i = 0; i<=n; i++) head[i] = -1;for(int i = 1; i<=m; i++) add(st,i,1),add(i,st,0);for(int i = m+1; i<=n; i++) add(i,ed,1),add(ed,i,0);for(int a,b;; ) {scanf("%d%d",&a,&b);if(a == -1 && b == -1) break;add(a,b,1);add(b,a,0);}int ans = dinic();if(ans == 0) puts("No Solution!");else {printf("%d\n",ans); for(int u = 1; u<=m; u++) {for(int i = head[u]; ~i; i = e[i].ne) {int v = e[i].to;if(v == st) continue;if(e[i].w == 0) {printf("%d %d\n",u,v);}}}}return 0; }?
總結
以上是生活随笔為你收集整理的【洛谷 - P2756】飞行员配对方案问题(网络流最大流,输出方案)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【BZOJ - 2574】[Poi199
- 下一篇: 【蓝桥官网试题 - 算法提高】chang