zoukankan      html  css  js  c++  java
  • 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;
    }
    

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

  • 相关阅读:
    AndroidのActivity启动模式
    Android 垃圾回收,用软引用建立缓存
    如何在eclipse的配置文件里指定jdk路径
    Chrome浏览器扩展开发系列之二:Google Chrome浏览器扩展的调试
    Chrome浏览器扩展开发系列之三:Google Chrome浏览器扩展的架构
    Chrome浏览器扩展开发系列之四:Browser Action类型的Chrome浏览器扩展
    Chrome浏览器扩展开发系列之五:Page Action类型的Chrome浏览器扩展
    Chrome浏览器扩展开发系列之六:options 页面
    手把手教你开发Chrome扩展三:关于本地存储数据
    手把手教你开发Chrome扩展二:为html添加行为
  • 原文地址:https://www.cnblogs.com/smilesundream/p/5501816.html
Copyright © 2011-2022 走看看