M_sea

洛谷2756 飞行员配对方案问题
题目描述英国皇家空军从沦陷国征募了大量外籍飞行员。由皇家空军派出的每一架飞机都需要配备在航行技能和语言上能互相配合...
扫描右侧二维码阅读全文
07
2017/10

洛谷2756 飞行员配对方案问题

题目描述

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

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

传送门

算法

裸的匈牙利算法即可。。。

至于输出匹配方案,当匹配到的人不是0时输出即可。。。

代码

#include <algorithm>
#include <iostream>
#include <cstdlib>
#include <cstring>
#include <cstdio>
#define re register
using namespace std;
inline int read() //快读
{
    int X=0,w=1; char ch=getchar();
    while (ch<'0'||ch>'9') { if (ch=='-') w=-1; ch=getchar(); }
    while (ch>='0'&&ch<='9') X=(X<<3)+(X<<1)+ch-'0',ch=getchar();
    return X*w;
}
bool vis[210];
int n,m,k;
int ans=0;
int link[210],head[210],cnt=0; //link[i]表示与第i个人匹配的人
struct Edge //邻接表
{
    int v,nxt;
    Edge() { this->v=this->nxt=0; }
}e[40010];
inline void addEdge(int u,int v) //加边
{
    cnt++;
    e[cnt].v=v;
    e[cnt].nxt=head[u];
    head[u]=cnt;
}
inline bool Hungary(int u) //匈牙利算法
{
    for (re int i=head[u];i;i=e[i].nxt) { //扫描所有人
        int v=e[i].v;
        if (!vis[v]) { //没有访问过
            vis[v]=true; //标记
            if (!link[v]||Hungary(link[v])) { //能匹配
                link[v]=u; //匹配
                return true; //匹配成功
            }
        }
    }
    return false; //匹配失败
}
int main()
{
    n=read(); m=read();
    int u=0,v=0;
    while (u!=-1&&v!=-1) { //输入、建图
        u=read(); v=read();
        if (u==-1&&v==-1) break;
        addEdge(u,v);
    }
    for (re int i=1;i<=n;i++) { //匹配每个人
        memset(vis,0,sizeof(vis));
        if (Hungary(i)) ans++;
    }
    if (ans==0) printf("No Solution!\n"); //没有人被匹配就无解
    else {
        printf("%d\n",ans); //输出匹配数
        for (re int i=1;i<=m;i++)
            if (link[i]) printf("%d %d\n",link[i],i); //输出匹配对
    }
    return 0;
}
最后修改:2018 年 11 月 09 日 04 : 22 PM

发表评论