1. 程式人生 > >hdu 3829 Cat VS Dog 二分匹配 最大獨立點集

hdu 3829 Cat VS Dog 二分匹配 最大獨立點集

closed count eof 最大 技術 size src int target

題目鏈接:http://acm.hdu.edu.cn/showproblem.php?pid=3829

題目大意:

給定N個貓,M個狗,P個小朋友,每個小朋友都有喜歡或者不喜歡的某貓或者某狗

管理員從中刪除一些貓狗,使得盡可能多的小朋友開心

思路:

假設A小朋友喜歡的貓是B小朋友所不喜歡的,或者說A不喜歡的狗是B喜歡的,那麽說明兩者之間存在矛盾關系

問題就是求出互相之間沒有矛盾的小朋友的集合

那麽就是點數-最大匹配數的問題了,就是讀入數據有點麻煩

代碼:

技術分享圖片
 1 #include <iostream>
 2 #include <string>
 3
#include <map> 4 #include <stdio.h> 5 #include <string.h> 6 using namespace std; 7 const int maxn=505; 8 int N,M,P,c_cnt,d_cnt; 9 int g[maxn][maxn],vis[maxn],who[maxn]; 10 struct node { 11 int data[2][205];//[0][]like [1][]don‘t like 12 } ans[maxn]; 13 map<string,int
> c,d; 14 map<string,int>::iterator it; 15 string s; 16 void rs(int i,int dir) { 17 if(s[0]==C) { 18 if(!c.count(s)) c.insert(pair<string,int>(s,c_cnt++)); 19 it=c.find(s); 20 ans[i].data[dir][it->second]=1; 21 } else { 22 if(!d.count(s)) d.insert(pair<string
,int>(s,d_cnt++)); 23 it=d.find(s); 24 ans[i].data[dir][it->second]=1; 25 } 26 } 27 void read() { 28 memset(g,0,sizeof(g)); 29 memset(who,0,sizeof(who)); 30 memset(ans,0,sizeof(ans)); 31 c.clear(); 32 d.clear(); 33 c_cnt=1; 34 d_cnt=101; 35 for(int i=1; i<=P; ++i) { 36 cin>>s;//like 37 int dir=0; 38 rs(i,dir); 39 cin>>s;//don‘t like 40 dir^=1; 41 rs(i,dir); 42 } 43 for(int i=1; i<=P; ++i) 44 for(int j=i+1; j<=P; ++j) 45 for(int k=1; k<=200; ++k) 46 if((ans[i].data[0][k]==1&&ans[j].data[1][k]==1)||(ans[i].data[1][k]==1&&ans[j].data[0][k]==1)) 47 g[i][j]=g[j][i]=1; 48 } 49 bool Find(int x) { 50 for(int i=1; i<=P; ++i) { 51 if(g[x][i]&&!vis[i]) { 52 vis[i]=1; 53 if(!who[i]||Find(who[i])) { 54 who[i]=x; 55 return true; 56 } 57 } 58 } 59 return false; 60 } 61 void slove() { 62 int sum=0; 63 for(int i=1; i<=P; ++i) { 64 memset(vis,0,sizeof(vis)); 65 if(Find(i)) sum++; 66 } 67 cout<<P-sum/2<<endl; 68 } 69 int main() { 70 while(cin>>N>>M>>P) { 71 read(); 72 slove(); 73 } 74 return 0; 75 }
View Code

hdu 3829 Cat VS Dog 二分匹配 最大獨立點集