HDOJ 3829 Cat VS Dog

Cat VS DogTime Limit: 2000/1000 MS (Java/Others)    Memory Limit: 125536/65536 K (Java/Others)
Total Submission(s): 2561    Accepted Submission(s): 875


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 child's like-animal is a cat, then his/hers dislike-animal must be a dog, and vice versa.
Now the zoo administrator is removing some animals, if one child's like-animal is not removed and his/hers dislike-animal is removed, he/she will be happy. So the administrator wants to know which animals he should remove to make maximum number of happy children.
 

Input
The input file contains multiple test cases, for each case, the first line contains three integers N <= 100, M <= 100 and P <= 500.
Next P lines, each line contains a child's like-animal and dislike-animal, C for cat and D for dog. (See sample for details)
 

Output
For each case, output a single integer: the maximum number of happy children.
 

Sample Input
1 1 2 C1 D1 D1 C1 1 2 4 C1 D1 C1 D1 C1 D2 D2 C1
 

Sample Output
1 3
Hint
Case 2: Remove D1 and D2, that makes child 1, 2, 3 happy.
 

Source
 
題意:動物園裏面只有貓和狗,對於每個人有喜歡的動物和不喜歡的動物,現在要刪除一些動物,讓最多的人滿意,也就是最多的人喜歡的動物保留下來並且不喜歡的動物被刪除。
直接來看結論,當達到最多的人的時候,留下來的人,沒有矛盾,也就是沒有人喜歡的動物是其他人不喜歡的動物,其餘的人都是和這些人有矛盾的人,將這些人按照矛盾來劃分爲不同的集合,所有這裏求的就是最大的集合,也就是圖論中的最大獨立集合,我們按照矛盾將這些人建邊,如果兩個人有矛盾,我們就在這兩個人之間連邊,最後求出最大的二分匹配,然後用人數剪出匹配的人數,剩下的就是答案。

#include<algorithm>
#include<stdio.h>
#include<queue>
#include<string>
#include<iostream>
#include<string.h>
#include<vector>
#include<map>
using namespace std;
int use[5005];
int r[5005];
vector<int> a[5005];
int n,m,p;
bool match(int now)
{
    int len=a[now].size();
    for(int i=0;i<len;i++)
    {
        if(use[a[now][i]]==1)
            continue;
        use[a[now][i]]=1;
        if(r[a[now][i]]==-1||match(r[a[now][i]]))
        {
            r[a[now][i]]=now;
            return true;
        }
    }
    return false;
}
int solve()
{
    int ans=0;
    for(int i=1;i<=p;i++)
    {
        memset(use,0,sizeof(use));    //初始化
        if(match(i))
            ans++;
    }
    return ans;
}
int main()
{
    while(scanf("%d%d%d",&n,&m,&p)!=EOF)
    {
        for(int i=0;i<=5000;i++)
            a[i].clear();
        memset(r,-1,sizeof(r));
        map<int,string>like;
        map<int,string>notlike;
        string c1,c2;
        for(int i=1;i<=p;i++)
        {
            cin>>c1>>c2;
            like[i]=c1;
            notlike[i]=c2;
        }
        for(int i=1;i<p;i++)
        {
            for(int j=i+1;j<=p;j++)
            {
                if(like[i]==notlike[j]||notlike[i]==like[j])
                {
                    a[i].push_back(j);
                    a[j].push_back(i);
                }
            }
        }
        int ans=solve();
        printf("%d\n",p-ans/2);
    }
return 0;
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章