zoukankan      html  css  js  c++  java
  • hdu 2444(二分图) The Accomodation of Students

    http://acm.hdu.edu.cn/showproblem.php?pid=2444

    大意是给定n个学生,他们之间可能互相认识,首先判断能不能将这些学生分为两组,使组内学生不认识;

    现想将学生两两分组,且保证每一组的学生都认识,这样分组可达到的最大组数为多大?

    判断二分图,然后求匈牙利算法求最大匹配数

    染色法判断二分图(脑抽用vector跑的特别慢)

     1 #include<cstdio>
     2 #include<cstring>
     3 #include<vector>
     4 using namespace std;
     5 #define M 300
     6 vector<int>line[M];
     7 int judge[M],p[M],q[M],used[M];
     8 int n;
     9 int find()
    10 {
    11     memset(q,0,sizeof(q));
    12     int start=0,end=1;
    13     q[start]=1;
    14     memset(judge,-1,sizeof(judge));
    15     judge[1]=0;
    16     while (start<end)
    17     {
    18         int w=q[start];
    19         for (int i=0;i<line[w].size();i++)
    20         {
    21             int e=line[w][i];
    22             if (judge[e]==-1){
    23                     judge[e]=(judge[w]+1)%2;
    24                     q[end++]=e;
    25             }
    26             else{
    27                 if (judge[e]==judge[w]) return 0;
    28             }
    29         }
    30         start++;
    31     }
    32     return 1;
    33 }
    34 int sreach(int x)
    35 {
    36     int i,j;
    37     for (j=1;j<=n;j++){
    38     for (i=0;i<line[j].size();i++)
    39     {
    40         if (line[j][i]==x&&!used[j])
    41         {
    42             used[j]=1;
    43             if (!p[j]||sreach(p[j]))
    44             {
    45                 p[j]=x;
    46                 return 1;
    47             }
    48         }
    49     }
    50     }
    51     return 0;
    52 }
    53 int main()
    54 {
    55     int t,i,m,a,b;
    56     while (~scanf("%d %d",&n,&m))
    57     {
    58         for (i=0;i<=n;i++)
    59             line[i].clear();
    60         while (m--)
    61         {
    62             scanf("%d %d",&a,&b);
    63             line[a].push_back(b);
    64             line[b].push_back(a);
    65         }
    66         memset(p,0,sizeof(p));
    67         if (!find()){
    68             printf("No
    ");continue;
    69         }
    70         int ans=0;
    71         for (i=1;i<=n;i++)
    72         {
    73             memset(used,0,sizeof(used));
    74             if (sreach(i)) ans++;
    75         }
    76         printf("%d
    ",ans/2);
    77     }
    78     return 0;
    79 }

    关系并查集判断二分图,类似于hdu 1829

    #include<cstdio>
    #include<cstring>
    using namespace std;
    #define M 300
    int father[M],line[M][M],used[M],p[M];
    int n,rank[M];
    void give()
    {
        for (int i=0;i<=200;i++){
            father[i]=i;rank[i]=0;
        }
    }
    int find(int x)
    {
        if (x==father[x]) return father[x];
        int t=find(father[x]);
        rank[x]=(rank[x]+rank[father[x]])%2;
        father[x]=t;
        return father[x];
    }
    int sreach(int x,int n)
    {
        int i;
        for (i=1;i<=n;i++)
        {
            if (line[i][x]&&!used[i])
            {
               used[i]=1;
               if (!p[i]||sreach(p[i],n))
               {
                   p[i]=x;
                   return 1;
               }
            }
        }
        return 0;
    }
    int main()
    {
        int n,m,a,b,i;
        while (~scanf("%d %d",&n,&m))
        {
            give();
            int flag=0;
            memset(p,0,sizeof(p));
            memset(line,0,sizeof(line));
            while (m--)
            {
                scanf("%d %d",&a,&b);
                line[a][b]=line[b][a]=1;
                int sx=find(a);
                int sy=find(b);
                if (sx!=sy) {
                    rank[sx]=(rank[a]+rank[b]+1)%2;
                    father[sx]=sy;
                }
                else {
                    if (rank[a]==rank[b]) flag=1;
                }
            }
            if (flag==1){
                printf("No
    ");continue;
            }
            int ans=0;
            for (i=1;i<=n;i++)
            {
                memset(used,0,sizeof(used));
                if (sreach(i,n)) ans++;
            }
            printf("%d
    ",ans/2);
        }
        return 0;
    }
  • 相关阅读:
    .NET基础之:i++和i=i+1和++i的区别
    几个缩写
    下一步工作的一些思考和问题
    显著提高应变的定位精度和颗粒大小
    两个使用的Ajax Demo
    SQL Service查询分析
    自学面向对象
    支持定位当前页,自定义排序的分页SQL(拒绝动态SQL)
    WCF学习经验分享,如何更好地学习WCF?
    Custom DataContractSerializerOperationBehavior
  • 原文地址:https://www.cnblogs.com/JJCHEHEDA/p/4952958.html
Copyright © 2011-2022 走看看