• P2756 飞行员配对方案问题


    传送门

    二分图

    稍微讲一下二分图:

    就是一个图分成两个部分A和B,这个图的无向边只连接不同的两个部分,即边不能在A或B的内部自己连自己

    然后问你最大能找到多少匹配

    匹配是指 A中的一个点与B中的一个点有边 并且 这两个点都还没有与其它点匹配

    这种问题一般用匈牙利算法:

      匈牙利算法的思想很简单

      对于一个点a能否找到另一个点匹配

      深搜a

      如果与a相连的这个点b还没匹配

      那么毫无问题a可以和b匹配

      但是如果b有匹配了

      没事,去问一下与b匹配的点能不能找其它的点匹配

      方法就是继续深搜(深搜与b匹配的点能否找到再另一个点匹配......)

      然后一直下去

      如果最终找到了

      回来,更新匹配


    本题是十分显然的二分图

    把每个英国飞行员连一条边到外籍飞行员上

    用匈牙利算法找到最大匹配

    顺便输出存储匹配的数组match就OK

    当然也可以用网络流,然而不如二分图好写

    (能用匈牙利为什么要用网络流..)

    顺便提一下网络流怎么写:

    建两个虚拟节点0和n+1,用0节点连接所有的外籍飞行员,用n+1连接所有英国飞行员

    然后所有的边边权都为1

    最后从0到n+1跑最大流就可以了

    以下为匈牙利算法(网络流是不可能有的)

    #include<iostream>
    #include<cstdio>
    #include<cmath>
    #include<cstring>
    #include<algorithm>
    #include<vector>
    using namespace std;
    inline int read()
    {
        register int x=0; int f=1;
        char ch=getchar();
        while(ch<'0'||ch>'9')
        {
            if(ch=='-') f=-1;
            ch=getchar();
        }
        while(ch>='0'&&ch<='9')
        {
            x=(x<<1)+(x<<3)+(ch^48);
            ch=getchar();
        }
        return x*f;
    }//快读
    int fir[10007],to[10007],from[10007],cnt;
    inline void add(int &a,int &b)
    {
        from[++cnt]=fir[a];
        fir[a]=cnt;
        to[cnt]=b;
    }//链式前向星存图
    int match[107];
    //匹配数组(划重点),match[i]表示与 编号为i的英国飞行员 的匹配的外籍飞行员的编号
    int n,m,ans;
    bool vis[107];
    inline bool dfs(int x)//如果dfs返回1就表示找到了一种方案(即编号为x的外籍飞行员找到了一个英国飞行员可以匹配)
    {
        for(int i=fir[x];i;i=from[i])
        {
            int u=to[i];
            if(vis[match[u]]) continue;
            vis[match[u]]=1;
            if(!match[u]||dfs(match[u]))//如果这个英国飞行员u还没被匹配,或者与Ta匹配的外籍飞行员可以找另一个人匹配
            {
                match[u]=x;//那么就把这个英国飞行员u的匹配的人改变成x号的外籍飞行员
                return 1;//并返回
            }
        }
    return 0;
    }//匈牙利算法
    int main()
    {
        int a,b;
        cin>>n>>m;
        while(1)
        {
            a=read(); b=read();
            if(a==-1&&b==-1) break;
            add(a,b);//存图
        }
        for(int i=1;i<=n;i++)
        {
            memset(vis,0,sizeof(vis));
            if(dfs(i))
              ans++;//多找到一种方案就把最大匹配数加1
        }
        cout<<ans<<endl;
        for(int i=1;i<=m;i++)
            if(match[i])//如果这个英国飞行员有人可以匹配
                printf("%d %d
    ",match[i],i); //输出每个外籍飞行员的编号和与之匹配的英国飞行员的编号
        return 0;
    }
  • 相关阅读:
    Spring 中出现Element : property Bean definitions can have zero or more properties. Property elements correspond to JavaBean setter methods exposed by the bean classes. Spring supports primitives, refer
    java定时器schedule和scheduleAtFixedRate区别
    hql语句中的select字句和from 字句
    使用maven搭建hibernate的pom文件配置
    Failure to transfer org.apache.maven:maven-archiver:pom:2.5 from http://repo.maven.apache.org/ maven2 was cached in the local repository, resolution will not be reattempted until the update interv
    对于文件File类型中的目录分隔符
    hibernate的事务管理和session对象的详解
    解决mac 中的myeclipse控制台中文乱码问题
    ibatis selectKey用法问题
    Java中getResourceAsStream的用法
  • 原文地址:https://www.cnblogs.com/LLTYYC/p/9508310.html
Copyright © 2020-2023  润新知