题意:
有猫C个和狗D个,有V个投票人,每个人喜欢猫讨厌狗或则喜欢狗讨厌猫!
求最多能满足多少投票人。
分析:
两个投票者矛盾的话就连一条边,总数减去最大匹配数/2就是要求的答案
// File Name: ACM/HDU/2768.cpp // Author: Zlbing // Created Time: 2013年08月16日 星期五 15时14分15秒 #include<iostream> #include<string> #include<algorithm> #include<cstdlib> #include<cstdio> #include<set> #include<map> #include<vector> #include<cstring> #include<stack> #include<cmath> #include<queue> using namespace std; #define CL(x,v); memset(x,v,sizeof(x)); #define INF 0x3f3f3f3f #define LL long long #define REP(i,r,n) for(int i=r;i<=n;i++) #define RREP(i,n,r) for(int i=n;i>=r;i--) const int MAXN=505; int Left[MAXN];//Left[i]为左边与右边第i个点匹配的编号 int w[MAXN][MAXN]; bool S[MAXN],T[MAXN]; int N; bool match(int i) { S[i]=true; for(int j=1;j<=N;j++)if(w[i][j]&&!T[j]) { T[j]=true; if(Left[j]==0||match(Left[j])) { Left[j]=i; return true; } } return false; } int hungry(){ CL(Left,0); int sum=0; for(int i=1;i<=N;i++) { CL(S,0); CL(T,0); if(match(i))sum++; } return sum; } string A[MAXN],B[MAXN]; int main() { int T; scanf("%d",&T); while(T--) { int n,m,k; scanf("%d%d%d",&n,&m,&k); REP(i,1,k) cin>>A[i]>>B[i]; CL(w,0); REP(i,1,k) REP(j,i+1,k) { if(A[i]==B[j]||B[i]==A[j]) { w[i][j]=w[j][i]=1; } } N=k; int ans=k-hungry()/2; printf("%d\n",ans); } return 0; }