洛谷2756 飞行员配对方案问题
题目描述
英国皇家空军从沦陷国征募了大量外籍飞行员。由皇家空军派出的每一架飞机都需要配备在航行技能和语言上能互相配合的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!’。
题解
很简单的二分图匹配题,匈牙利水题,但是题目是先输入m再输入n的,眼瞎的我看了许久才找的自己的问题。
#include<iostream> #include<algorithm> #include<cstring> #include<cstdio> using namespace std; #define maxn 105 using namespace std; int link[maxn]; int head[maxn]; bool vis[maxn]; int n,m,cnt,ans; struct edge{ int next,to; }e[maxn*maxn]; void insert(int u,int v){ cnt++; e[cnt].next=head[u];e[cnt].to=v; head[u]=cnt; } bool dfs(int x){ for(int i=head[x];i;i=e[i].next){ int s=e[i].to; if(!vis[s]){ vis[s]=1; if(!link[s]||dfs(link[s])){ link[s]=x; return 1; } } } return 0; } int main(){ scanf("%d%d",&m,&n); int i,j; while(1){ scanf("%d%d",&i,&j); if(i==-1&&j==-1)break; insert(i,j); } for(int i=1;i<=m;i++){ memset(vis,0,sizeof vis); if(dfs(i))ans++; } if(ans){ printf("%d\n",ans); for(int i=m+1;i<=n;i++){ if(link[i]){ printf("%d %d\n",link[i],i); } } } else{ printf("No Solution!"); } }
补上一下网络流代码
#include<iostream> #include<cstdio> #include<algorithm> #include<cstring> using namespace std; #define maxn 205 struct edge{ int next,to,w; }e[maxn*maxn]; int n,m,ans,ne=1; int head[maxn],h[maxn],q[maxn],father[maxn]; void insert(int u,int v,int w) { ne++; e[ne].to=v; e[ne].w=w; e[ne].next=head[u]; head[u]=ne; ne++; e[ne].to=u; e[ne].next=head[v]; head[v]=ne; } bool bfs() { int now,t=0,w=1,p,i; memset(h,-1,sizeof(h)); q[t]=h[0]=0; while(t<w) { now=q[t];t++; i=head[now]; while(i) { if(e[i].w&&h[e[i].to]<0) { q[w++]=e[i].to; h[e[i].to]=h[now]+1; } i=e[i].next; } } if(h[n+1]==-1)return 0; return 1; } int dfs(int x,int f) { if(x==n+1)return f; int i=head[x]; int w,used=0; while(i) { if(e[i].w&&h[e[i].to]==h[x]+1) { w=f-used; w=dfs(e[i].to,min(w,e[i].w)); if(w)father[x]=e[i].to; e[i].w-=w; e[i^1].w+=w; used+=w; if(used==f)return f; } i=e[i].next; } if(!used)h[x]=-1; return used; } void dinic(){ while(bfs()){ ans+=dfs(0,0x7fffffff); } } int main(){ scanf("%d%d",&m,&n); int x,y; scanf("%d%d",&x,&y); while(x!=-1){ insert(x,y,1); scanf("%d%d",&x,&y); } for(int i=1;i<=m;i++) insert(0,i,1); for(int i=m+1;i<=n;i++) insert(i,n+1,1); dinic(); if(ans)printf("%d\n",ans); else { puts("No Solution!"); return 0; } for(int i=1;i<=m;i++){ if(father[i])printf("%d %d\n",i,father[i]); } return 0; }