zoukankan      html  css  js  c++  java
  • hoj 2524 Allocate Dormitories 二分图的最大匹配

    /*

    题目:

        哈工大推出新的宿舍分配方案,当两人对A B题有相同答案的人可以分在A类宿舍,

        C D题有相同答案的人可以分在B类宿舍,每一间的宿舍人数没有限制的话,问可

        以最少要分配多少间宿舍才能分好所有学生

    分析:

        每一个学生都可以分配在A类宿舍i,或者B类宿舍j,因此,g[i][j] = true,由此可以

        构造一个二分图,用hungry算法做

        由于输入的数据比较大,若用两层循环判断的话,会超时,所以可以先排序,然后再判断

        与前面的一不一样,若一样则置g[i][j] = true,i j的值需要先处理好,具体看代码

    */

    #include <iostream>

    #include <cstring>

    #include <cstdio>

    #include <algorithm>

    using namespace std;

    #define X 102

    int ym[X],na,nb;

    bool g[X][X],use[X];

    struct node

    {

           int a,b,c,d;

           int na,nb;                    //所在的宿舍A B的房间号

    }p[X*X];

    bool cmp1(node a,node b)//对前两个关键字排序

    {

           if(a.a==b.a)

                  return a.b<b.b;

           else

                  return a.a<b.a;

    }

    bool cmp2(node a,node b)//对后两个关键字进行排序

    {

           if(a.c==b.c)

                  return a.d<b.d;

           else

                  return a.c<b.c;

    }

    bool dfs(int u)//寻找一条增广路

    {

           int t;

           for(int v=1;v<=nb;v++)

                  if(g[u][v]&&!use[v])

                  {

                         use[v] = true;

                         t = ym[v];

                         ym[v] = u;    //路径取反操作

                         if(t==-1||dfs(t))//寻找是否为增广轨

                                return true;

                         ym[v] = t;

                  }

                  return false;

    }

    int hungry()  //

    {

           memset(ym,-1,sizeof(ym));

           int ret = 0;                  //初始时增广轨为空

           for(int u=1;u<=na;u++)//从二分图的左部的每个顶点开始寻找增广轨

           {

                  memset(use,false,sizeof(use));

                  if(dfs(u))                    //若找到,把它取反,总匹配加一

                         ret++;

           }

           return ret;                          //返回最大匹配数

    }

    int main()

    {

           freopen("sum.in","r",stdin);

           freopen("sum.out","w",stdout);

           int n,t;

           scanf("%d",&t);

           while(t--)

           {

                  scanf("%d",&n);

                  for(int i=0;i<n;i++)

                         scanf("%d%d%d%d",&p[i].a,&p[i].b,&p[i].c,&p[i].d);

                  sort(p,p+n,cmp1);

                  na = nb = 1;

                  p[0].na = p[0].nb = 1;

                  int ta = p[0].a,tb = p[0].b;

                  for(int i=1;i<n;i++)            //A型宿舍进行标号

                  {

                         if(p[i].a==ta&&p[i].b==tb)      //如果与前面的一样的话,在A型宿舍的位置与当前的B型宿舍总数一样

                                p[i].na = na;

                         else                                    //否则,B型宿舍总数加一

                         {

                                p[i].na = ++na;

                                ta = p[i].a;                   //更新

                                tb = p[i].b;

                         }

                  }

                  memset(g,false,sizeof(g));

                  sort(p,p+n,cmp2);       //对后两个关键字进行排序

                  int tc = p[0].c,td = p[0].d;

                  for(int i=0;i<n;i++)

                  {

                         if(p[i].c==tc&&p[i].d==td)      //如果与前面的一样的话,在B型宿舍的位置与当前的B型宿舍总数一样

                                p[i].nb = nb;

                         else                                    //否则,B型宿舍总数加一

                         {

                                p[i].nb = ++nb;

                                tc = p[i].c;                   //更新

                                td = p[i].d;

                         }

                         g[p[i].na][p[i].nb] = true;//相当于A型宿舍iB型宿舍j相连

                  }

                  printf("%d\n",hungry());

           }

           return 0;

    }

     

  • 相关阅读:
    golang删除数组某个元素
    golang用通道实现信号量,控制并发个数
    什么是ScaleIO中的forwards rebuild和backwards rebuild?
    SQL Server中的database checkpoint
    如何将thick provision lazy zeroed的VMDK文件转换为thick provision eager zeroed?
    LoadTestAgentResultsLateException in VS2010
    SQL Server Instance无法启动了, 因为TempDB所在的分区没有了, 怎么办?
    VMware vCenter中, 如何辩认虚机上Raw Device Mapping过了的一块物理磁盘?
    SQL Server AlwaysOn Setup Step-By-Step Guide
    TPC-E在populate测试Database时需要注意的一些事项
  • 原文地址:https://www.cnblogs.com/yejinru/p/2436078.html
Copyright © 2011-2022 走看看