• POJ 3692 幼儿园做游戏 最大团 模板题


    Kindergarten
    Time Limit: 2000MS   Memory Limit: 65536K
    Total Submissions: 6191   Accepted: 3052

    Description

    In a kindergarten, there are a lot of kids. All girls of the kids know each other and all boys also know each other. In addition to that, some girls and boys know each other. Now the teachers want to pick some kids to play a game, which need that all players know each other. You are to help to find maximum number of kids the teacher can pick.

    Input

    The input consists of multiple test cases. Each test case starts with a line containing three integers
    GB (1 ≤ GB ≤ 200) and M (0 ≤ M ≤ G × B), which is the number of girls, the number of boys and
    the number of pairs of girl and boy who know each other, respectively.
    Each of the following M lines contains two integers X and Y (1 ≤ X≤ G,1 ≤ Y ≤ B), which indicates that girl X and boy Y know each other.
    The girls are numbered from 1 to G and the boys are numbered from 1 to B.

    The last test case is followed by a line containing three zeros.

    Output

    For each test case, print a line containing the test case number( beginning with 1) followed by a integer which is the maximum number of kids the teacher can pick.

    Sample Input

    2 3 3
    1 1
    1 2
    2 3
    2 3 5
    1 1
    1 2
    2 1
    2 2
    2 3
    0 0 0

    Sample Output

    Case 1: 3
    Case 2: 4

    Source

    题意:在幼儿园中,有许多小孩。其中有男孩,也有女孩。女孩之间相互认识,男孩之间也相互认识。同时,一些男孩和女孩之间也相互认识,有一天,老师希望从所有人之中选出一些人来玩游戏,这个游戏需要所有的参与者之间相互认识,问老师可以最多找出多少人来玩这个游戏。
    #include <cstdio>
    #include <algorithm>
    #include <cstring>
    #include <iostream>
    #include <cmath>
    #include <vector>
    #define MM(a,b)  memset(a,b,sizeof(a))
    using namespace std;
    
    vector<int> G[505];
    int match[505],used[505];
    int g,b,m;
    int mp[505][505];
    void add_edge(int u,int v)
    {
        G[u].push_back(v);
        G[v].push_back(u);
    }
    
    bool dfs(int u)
    {
         used[u]=1;
         for(int i=0;i<G[u].size();i++)
         {
           int v=G[u][i];
           int w=match[v];
           if(w<0||!used[w]&&dfs(w))
             {
                 match[u]=v;
                 match[v]=u;//匹配的边两端点同时标记
                 return true;
             }
         }
         return false;
    }
    
    int  bipartite_match()
    {
        memset(match,-1,sizeof(match));
        int res=0;
        for(int i=1;i<=g+b;i++)
          if(match[i]<0)//先前标记过就不用再标记了
          {
              memset(used,0,sizeof(used));
              if(dfs(i)) res++;
          }
        return res;
    }
    
    int main()
    {
        int kk=0;
        while(~scanf("%d %d %d",&g,&b,&m)&&(g||b||m))
        {
            MM(mp,0);
            for(int i=1;i<=g+b;i++) G[i].clear();
            for(int i=1;i<=m;i++)
            {
                int u,v;
                scanf("%d %d",&u,&v);
                mp[u][v]=1;
            }
            for(int i=1;i<=g;i++)
                for(int j=1;j<=b;j++)
                  if(!mp[i][j])
                    add_edge(i,j+g);
            printf("Case %d: %d
    ",++kk,g+b-bipartite_match());
        }
        return 0;
    }
    

      分析:很显然的是求一个最大团,求大团中,但是因为男生与男生之间以及女生与女生之间是互相认识的,又不能在二分图中的同一侧之间相互连边,那么就只有转换为补图,求补图的最大点独立集

  • 相关阅读:
    大数运算(涉及到格式问题)
    UltraEdit
    汉化eclipse3.6.2
    安装Microsoft SQL Server Management Studio Express是报错29506
    Java相对路径/绝对路径
    恢复Unbuntu的启动项
    UNC路径
    make: g++:命令未找到
    找到个学习html的网站
    HDU 3756 三分
  • 原文地址:https://www.cnblogs.com/smilesundream/p/5501816.html
Copyright © 2020-2023  润新知