【网络流24题】——搭配飞行员

飞行大队有若干个来自各地的驾驶员,专门驾驶一种型号的飞机,这种飞机每架有两个驾驶员,需一个正驾驶员和一个副驾驶员。由于种种原因,例如相互配合的问题,有些驾驶员不能在同一架飞机上飞行,问如何搭配驾驶员才能使出航的飞机最多呢?
P.S.因为驾驶工作分工严格,两个正驾驶员或两个副驾驶员都不能同机飞行。
输入
第一行,两个整数 n 与m,表示共有 n 个飞行员,其中有 m 名飞行员是正驾驶员。 下面有若干行,每行有 2 个数字a、 b。表示正驾驶员 a 和副驾驶员 b 可以同机飞行。 P.S.正驾驶员的编号在前,即正驾驶员的编号小于副驾驶员的编号。
输出
仅一行一个整数,表示最大起飞的飞机数。
样例输入
10 5
1 7
2 6
2 10
3 7
4 8
5 9
样例输出
4
提示
2≤n≤100

说都不用说了吧

二分图匹配或者网络流都可以做

二分图就直接匹配

网络流的话建一个源点向所有正飞行员每人连一条容量为1的边,再建一个汇点,所有副飞行员向其连一条容量为1的边,中间按题意连

二分图匹配代码

#include<bits/stdc++.h>
using namespace std;
inline int read(){
    char ch=getchar();
    int res=0;
    while(!isdigit(ch)) ch=getchar();
    while(isdigit(ch)) res=(res<<3)+(res<<1)+(ch^48),ch=getchar();
    return res;
}
int n,m,adj[500],nxt[10005],to[10005],lf[10005],cnt,rt[10005];
bool vis[10005];
inline void addedge(int u,int v){
    nxt[++cnt]=adj[u],adj[u]=cnt,to[cnt]=v;
}
inline int dfs(int u){
    for(int e=adj[u];e;e=nxt[e]){
        int v=to[e];
        if(vis[v])continue;
        vis[v]=1;
        if(!rt[v]||dfs(rt[v])){
            rt[v]=u,lf[u]=v;
            return true;
        }
    }
    return false;
}
int main(){
    n=read(),m=read();
    int u,v;
    while(scanf("%d%d",&u,&v)!=EOF){
        memset(vis,0,sizeof(vis));
        addedge(u,v);
    }
    for(int i=1;i<=m;i++){
        dfs(i);
    }
    int ans=0;
    for(int i=1;i<=m;i++){
        if(lf[i]!=0){
            ans++;
        }
    }
    cout<<ans<<'\n';
}
posted @ 2018-10-12 08:13  Stargazer_cykoi  阅读(138)  评论(0编辑  收藏  举报