二分匹配 Cat VS Dog (第一次 多校联盟 华东师大oj 2682 )

来源:互联网 发布:cookie flash.js 编辑:程序博客网 时间:2024/04/28 07:07

本意出在了第一次多校联盟中,很不幸,我这道题目竟然一个下午没有思路,但是之前一下,我刚学了二分匹配的啊,再次说明了,ACM的重点是在思维的训练,建模能力的锻炼,而对算法的熟练掌握和深入理解只是基础而已,要做好ACM,思维才是最主要的。

拿到这道题目,一开始我就进入到了题目的思维定势的陷阱中,以为拿人当边,狗猫分别做节点,于是这样的话就会出现边有权值,那么就KM???但是KM或许也是不对的,因为,如果有两个人喜欢同一个猫而讨厌不同的狗,那么这两条边在匹配时不同时出现,而实际是都可以要的。所以,本题目正确的做法是拿人当节点,我们反向思维,由于喜欢猫C1的和讨厌猫C1的两个人是一对矛盾,必然不能同时出现在结果中,那么我们去找到所有的矛盾数目的最大值,用总人数一减就OK了。

代码:

# include <math.h>
# include <stdio.h>
# include <string.h>
# include <stdlib.h>
# include <algorithm>
# include <iostream>
# include <string>
# include <queue>
# include <stack>
# include <map>
# include <set>
# include <vector>
# include <cstring>
# include <list>
# include <ctime>
# include <sstream>
using namespace std;
#define N 700
class node
{
  public:
  string like,unlike;
}p1[N],p2[N];
int cnt1,cnt2;
char like[10],unlike[10];
bool mp[N][N];
int r[N];
int l[N];
bool used[N];
int n,m;
bool dfs(int u){
    for(int v =1 ; v <=cnt2 ; v++){
        if(mp[u][v] && !used[v]){
            used[v] = true;   
            if(r[v] == -1 || dfs(r[v])){
              
                r[v] = u;   
                return true;
           }           
        }
    }
    return false;
}

int main()
{
 int cc,dd,p,i,j,T;
 scanf("%d",&T);
 while(T--)
 {
  memset(mp,0,sizeof(mp));//不要忘了!!
  scanf("%d%d%d",&cc,&dd,&p);
  cnt1=0;cnt2=0;
  for(i=1;i<=p;i++)
  {
   scanf("%s%s",like,unlike);
   
   if(like[0]=='C')
   {
     p1[++cnt1].like="";
     p1[cnt1].like+=like;
     p1[cnt1].unlike="";
     p1[cnt1].unlike+=unlike;
   }
  else if(like[0]=='D')
   {
     p2[++cnt2].like="";
     p2[cnt2].like+=like;
     p2[cnt2].unlike="";
     p2[cnt2].unlike+=unlike;
   }
  }
  
   for(i=1;i<=cnt1;i++)
   for(j=1;j<=cnt2;j++)
   if(p1[i].unlike==p2[j].like||p1[i].like==p2[j].unlike)
   mp[i][j]=1;
   
   for(i=1;i<=cnt2;i++)
   for(j=1;j<=cnt1;j++)
   if(p2[i].unlike==p1[j].like||p2[i].like==p1[j].unlike)
   mp[j][i]=1;
 
  
  int res = 0;
   
        memset(r,-1,sizeof(r));
         
        for(i=1;i<=cnt1;i++)
       {
            memset(used,false,sizeof(used));
       
           if(dfs(i))
           res++;   
      
        }
        printf("%d\n",p-res);
 }
 return 0;
}

 

原创粉丝点击