Luogu P2756 飞行员配对方案问题

这真的是一道二分图水题呵!

这道题就是根据题意连边+跑匈牙利(比Dinic好写)

具体的建模就是把外籍飞行员和皇家空军飞行员连起来,最大匹配即可

CODE

#include<cstdio>
#include<cstring>
using namespace std;
const int N=105;
struct edge
{
    int to,next;
}e[N*N];
int head[N<<1],n,m,x,y,from[N<<1],ans,k;
bool vis[N<<1];
inline char tc(void)
{
    static char fl[100000],*A=fl,*B=fl;
    return A==B&&(B=(A=fl)+fread(fl,1,100000,stdin),A==B)?EOF:*A++;
}
inline void read(int &x)
{
    x=0; char ch=tc(); int flag=1;
    while (ch<'0'||ch>'9') { if (ch=='-') flag=-1; ch=tc(); }
    while (ch>='0'&&ch<='9') x=x*10+ch-'0',ch=tc();
    x*=flag;
}
inline void write(int x)
{
    if (x/10) write(x/10);
    putchar(x%10+'0');
}
inline void add(int x,int y)
{
    e[++k].to=y; e[k].next=head[x]; head[x]=k;
}
inline bool find(int now)
{
    for (register int i=head[now];i!=-1;i=e[i].next)
    if (!vis[e[i].to])
    {
        vis[e[i].to]=1;
        if (!from[e[i].to]||find(from[e[i].to]))
        {
            from[e[i].to]=now;
            return 1;
        }
    }
    return 0;
}
int main()
{
    //freopen("CODE.in","r",stdin); freopen("CODE.out","w",stdout);
    register int i;
    memset(e,-1,sizeof(e));
    memset(head,-1,sizeof(head));
    read(m); read(n); read(x); read(y);
    while (x!=-1&&y!=-1) add(x,y),read(x),read(y);
    for (i=1;i<=m;++i)
    {
        memset(vis,0,sizeof(vis));
        ans+=find(i);
    }
    if (!ans) { puts("No Solution!"); return 0; }
    write(ans); putchar('\n');
    for (i=m+1;i<=n;++i)
    if (from[i]) write(from[i]),putchar(' '),write(i),putchar('\n');
    return 0;
}
posted @ 2018-04-07 13:43  空気力学の詩  阅读(131)  评论(0编辑  收藏  举报