题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3829
题目大意:
思路:如果A喜欢==B不喜欢||A不喜欢==B喜欢。那么A和B不能同时满足。连一条边。因为如果孩子的喜欢动物是猫,那么他/她的不喜欢动物一定是狗,反之亦然。那么可以证明一定一个二分图。就是求二分图的最大独立集。
#include <map>
#include <set>
#include <cmath>
#include <queue>
#include <cstdio>
#include <vector>
#include <climits>
#include <cstring>
#include <cstdlib>
#include <iostream>
#include <algorithm>
#define LL long long
using namespace std;
const int INF=1e9;
const int maxn=505;// 最大点数
vector<int> G[maxn];
int Mx[maxn],My[maxn],Nx,Ny;//Mx[i]表示左集合i顶点所匹配的右集合的顶点序号
int dx[maxn],dy[maxn],dis;//My[i]表示右集合i顶点所匹配的左集合的顶点序号
bool vis[maxn];
//寻找 增广路径集
bool searchP(){
queue<int> q;
dis=INF;
memset(dx,-1,sizeof(dx));
memset(dy,-1,sizeof(dy));
for(int i=1;i<=Nx;i++){
if(Mx[i]==-1){
q.push(i);dx[i]=0;
}
}
while(!q.empty()){
int u=q.front();q.pop();
if(dx[u]>dis) break;
for(int i=0;i<G[u].size();i++){
int v=G[u][i];
if(dy[v]==-1){
dy[v]=dx[u]+1;
if(My[v]==-1) dis=dy[v];
else{
dx[My[v]]=dy[v]+1;
q.push(My[v]);
}
}
}
}
return dis!=INF;
}
//寻找路径 深度搜索
bool dfs(int u){
for(int i=0;i<G[u].size();i++){
int v=G[u][i];
if(!vis[v]&&dy[v]==dx[u]+1){
vis[v]=1;
if(My[v]!=-1&&dy[v]==dis) continue;
if(My[v]==-1||dfs(My[v])){
My[v]=u;
Mx[u]=v;
return true;
}
}
}
return false;
}
//得到最大匹配的数目
int MaxMatch(){
int res=0;
memset(Mx,-1,sizeof(Mx));
memset(My,-1,sizeof(My));
while(searchP()){
memset(vis,0,sizeof(vis));
for(int i=1;i<=Nx;i++){
if(Mx[i]==-1&&dfs(i)) res++;
}
}
return res;
}
string s1[505], s2[505];
int main(){
int n1, n2, n3;
string a, b;
while(~scanf("%d%d%d", &n1, &n2, &n3)){
for(int i=1; i<=n3; i++){
cin>>a>>b;
s1[i]=a;
s2[i]=b;
}
for(int i=1; i<=n3; i++){
for(int j=i+1; j<=n3; j++){
if(s1[i]==s2[j]||s2[i]==s1[j]){
G[i].push_back(j);
G[j].push_back(i);
}
}
}
Nx=Ny=n3;
printf("%d\n", n3-MaxMatch()/2);
for(int i=1; i<=n3; i++) G[i].clear();
}
return 0;
}
京公网安备 11010502036488号