HDU 3829 Cat VS Dog(最大独立集)

题目大意:

有n只猫,有m只狗。现在有P个学生去参观动物园。每个孩子有喜欢的动物和不喜欢的动物。假如他喜欢猫那么他就一定不喜欢狗(反之亦然)。

如果一个孩子喜欢一个动物,那么这个动物不会被移除,若是不喜欢则移除。现在管理员想知道移除哪些动物可以使最大数量的孩子高兴。

输入数据:

输入包含多组测试实例。

第一行是三个数字n, m, p.

接下来p行。

每行 CX, DX 代表他喜欢第X只猫,讨厌第X只狗(反之亦然)

题目思路:

构图思路:我们把所有人进行构图,如果两个人之间有矛盾就建立一条边。然后求最大独立集就行了

二分图的最大独立集 : 二分图的最大独立集=图的点数  -  最大匹配数

可以这样理解,在总的点集中,去掉最少的点,使得剩下的点相互之间没有边。用最少的点去覆盖所有的边,也就是最小覆盖。

#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<iostream>
#include<vector>
#include<queue>
#include<cmath>
using namespace std;
#define INF 0x3fffffff
#define maxn 505
int n, m, p, P[maxn], color[maxn];///n只猫 m只狗 p个人
bool G[maxn][maxn], vis[maxn];///构图
vector<vector<int> > LikeDog;///喜欢第k只狗的人邻接表
vector<vector<int> > DisDog;///不喜欢这只够的人的集合
vector<vector<int> > LikeCat;///同上
vector<vector<int> > DisCat;

void Init()
{
    LikeDog.clear();
    LikeDog.resize(m+1);
    LikeCat.clear();
    LikeCat.resize(n+1);

    DisDog.clear();
    DisDog.resize(m+1);
    DisCat.clear();
    DisCat.resize(n+1);
    memset(G, false, sizeof(G) );
}

void MakeMap()
{
    for(int i=1; i<=m; i++)
    {
        int len1 = LikeDog[i].size();
        int len2 = DisDog[i].size();
        for(int j=0; j<len1; j++)
        {
            int v1 = LikeDog[i][j];
            for(int k=0; k<len2; k++)
            {
                int v2 = DisDog[i][k];
                G[v1][v2] = true;
                G[v2][v1] = true;
            }
        }
    }

    for(int i=1; i<=n; i++)
    {
        int len1 = LikeCat[i].size();
        int len2 = DisCat[i].size();
        for(int j=0; j<len1; j++)
        {
            int v1 = LikeCat[i][j];
            for(int k=0; k<len2; k++)
            {
                int v2 = DisCat[i][k];
                G[v1][v2] = true;
                G[v2][v1] = true;
            }
        }
    }
}
bool Find(int u)
{
    for(int i=1; i<=p; i++)
    {
        if(!vis[i] && G[u][i])
        {
            vis[i] = true;
            if(P[i] == -1 || Find(P[i]) )
            {
                P[i] = u;
                return true;
            }
        }
    }
    return false;
}
void DFS(int u,int Color)
{
    color[u] = Color;
    for(int i=1; i<=p; i++)
    {
        if(G[u][i] && !color[i])
        {
            DFS(i, -Color);
        }
    }
}

int solve()
{
    int ans = 0;
    memset(P, -1, sizeof(P));
    memset(color, 0, sizeof(color));

    for(int i=1; i<=p; i++)
    {
        if(color[i] == 0)
            DFS(i, 1);
    }
    for(int i=1; i<=p; i++)
    {
        memset(vis, false, sizeof(vis));
        if(color[i] == 1 && Find(i) )
            ans ++;
    }
    return p - ans;
}

int main()
{
    while(scanf("%d %d %d ",&n, &m, &p) != EOF)
    {
        char ch1, ch2;
        int a, b;
        Init();
        for(int i=1; i<=p; i++)
        {
            scanf("%c%d %c%d",&ch1, &a, &ch2, &b);
            getchar();
            if(ch1 == ‘C‘)
            {
                LikeCat[a].push_back(i);
                DisDog[b].push_back(i);
            }
            else
            {
                LikeDog[a].push_back(i);
                DisCat[b].push_back(i);
            }
        }
        MakeMap();
        printf("%d\n", solve() );
    }
    return 0;
}
时间: 2024-10-09 11:23:55

HDU 3829 Cat VS Dog(最大独立集)的相关文章

HDU 3829 - Cat VS Dog (二分图最大独立集)

题意:动物园有n只猫和m条狗,现在有p个小孩,他们有的喜欢猫,有的喜欢狗,其中喜欢猫的一定不喜欢狗,喜欢狗的一定不喜欢猫.现在管理员要从动物园中移除一些动物,如果一个小孩喜欢的动物留了下来而不喜欢的动物被移走,这个小孩会很高兴.现在问最多可以让多少个小孩高兴. 此题是求二分图最大独立集. 二分图比较明显,但是难在建图.这个题是找到最多的喜欢猫和喜欢狗而不互相冲突的小孩,这样我们将喜欢动物相互冲突的小孩之间连边,问题就变成了求二分图的最大独立集. 在二分图中,最大独立集=顶点数-最大匹配数. 求解

hdu 3829 Cat VS Dog 二分图匹配 最大点独立集

Cat VS Dog Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 125536/65536 K (Java/Others) Problem Description The zoo have N cats and M dogs, today there are P children visiting the zoo, each child has a like-animal and a dislike-animal, if the

hdu 3829 Cat VS Dog 二分匹配 最大独立点集

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3829 题目大意: 给定N个猫,M个狗,P个小朋友,每个小朋友都有喜欢或者不喜欢的某猫或者某狗 管理员从中删除一些猫狗,使得尽可能多的小朋友开心 思路: 假设A小朋友喜欢的猫是B小朋友所不喜欢的,或者说A不喜欢的狗是B喜欢的,那么说明两者之间存在矛盾关系 问题就是求出互相之间没有矛盾的小朋友的集合 那么就是点数-最大匹配数的问题了,就是读入数据有点麻烦 代码: 1 #include <iostream

HDU 3829 Cat VS Dog

题意: p个人  每个人有喜欢和讨厌的动物  如果选出的动物中包含这个人喜欢的动物同时不包含他讨厌的动物那么这个人会开心  问  最多几个人开心 思路: 二分图最大独立集  利用人与人之间的冲突建边  求最大匹配即可 注意: 题中的样例给出动物的名字是D1.C1之类的  其实名字可能比这个长-  所以数组开长点 代码: #include<cstdio> #include<iostream> #include<cstring> #include<string>

hdu 2768 Cat vs. Dog 最大独立集 巧妙的建图

题目分析: 一个人要不是爱狗讨厌猫的人,要不就是爱猫讨厌狗的人.一个人喜欢的动物如果离开,那么他也将离开.问最多留下多少人. 思路: 爱猫和爱狗的人是两个独立的集合.若两个人喜欢和讨厌的动物是一样的,那么就建一条边.留下多少人,就是求最大独立集. 最大独立集= 顶点数 - 最大匹配数 1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 #inc

hdu 2768 Cat vs. Dog (二分匹配)

Cat vs. Dog Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 1422    Accepted Submission(s): 534 Problem Description The latest reality show has hit the TV: ``Cat vs. Dog''. In this show, a bunch

HDU 3289 Cat VS Dog (二分匹配 求 最大独立集)

题意:每个人有喜欢的猫和不喜欢的狗.留下他喜欢的猫他就高心,否则不高心.问最后最多有几个人高心. 思路:二分图求最大匹配 1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 #include<iostream> 5 #include<cstdlib> 6 #include<string> 7 #include<cmath> 8 #include<

HDU——2768 Cat vs. Dog

Cat vs. Dog Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 2279    Accepted Submission(s): 886 Problem Description The latest reality show has hit the TV: ``Cat vs. Dog''. In this show, a bunc

Hdu_3829 Cat VS Dog -最大独立集+建图

题意:动物园有n种猫,m种狗,小孩子喜欢猫就讨厌狗,喜欢狗就讨厌猫,只要孩子们不喜欢的东西不在,他们就开心,问他们的最大开心度. 分析:建图是个难点,反正我是不会建的,搜了题解才意识到可以建"矛盾边"这种东西.只要孩子们喜欢的东西有冲突就连边,最后找到最大的独立集就是答案了 /************************************************ Author :DarkTong Created Time :2016/8/1 17:20:09 File Nam