1.飞行员配对方案问题
题意:每架飞机需要两个驾驶员,一个正驾驶员和一个副驾驶员。由于种种原因,有些驾驶员不能在同一架飞机上飞行,问如何搭配驾驶员才能使出航的飞机最多。两个正驾驶员或两个副驾驶员都不能同机飞行。
分析:二分图最大匹配裸题。
1 #include<cstdio> 2 #include<algorithm> 3 #include<cstring> 4 #define LL long long 5 using namespace std; 6 const int N=105; 7 const int inf=0x3f3f3f3f; 8 int n,m,x,y,S,T,cnt=1,ans; 9 int cur[N],first[N],dis[N],q[N]; 10 struct edge{int to,next,flow;}e[N*N*4]; 11 int read() 12 { 13 int x=0,f=1;char c=getchar(); 14 while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();} 15 while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();} 16 return x*f; 17 } 18 void insert(int u,int v,int w) 19 { 20 e[++cnt]=(edge){v,first[u],w};first[u]=cnt; 21 e[++cnt]=(edge){u,first[v],0};first[v]=cnt; 22 } 23 bool bfs() 24 { 25 memset(dis,-1,sizeof(dis)); 26 int head=0,tail=1; 27 q[head]=S;dis[S]=0; 28 while(head!=tail) 29 { 30 int u=q[head++]; 31 for(int i=first[u];i;i=e[i].next) 32 { 33 int v=e[i].to; 34 if(dis[v]!=-1||!e[i].flow)continue; 35 dis[v]=dis[u]+1; 36 q[tail++]=v; 37 } 38 } 39 return dis[T]!=-1; 40 } 41 int dfs(int u,int a) 42 { 43 if(u==T||a==0)return a; 44 int f,flow=0; 45 for(int& i=cur[u];i;i=e[i].next) 46 { 47 int v=e[i].to; 48 if(dis[v]==dis[u]+1&&(f=dfs(v,min(e[i].flow,a)))>0) 49 { 50 e[i].flow-=f;e[i^1].flow+=f; 51 flow+=f;a-=f;if(a==0)break; 52 } 53 } 54 return flow; 55 } 56 int main() 57 { 58 n=read();m=read();S=0;T=n+1; 59 while(scanf("%d%d",&x,&y)==2)insert(x,y,1); 60 for(int i=1;i<=m;i++)insert(S,i,1); 61 for(int i=m+1;i<=n;i++)insert(i,T,1); 62 while(bfs()) 63 { 64 for(int i=S;i<=T;i++)cur[i]=first[i]; 65 ans+=dfs(S,inf); 66 } 67 printf("%d\n",ans); 68 return 0; 69 }