二分图的最大点独立集
人可以看成两个集合,喜欢猫的那群人内部肯定不会冲突,喜欢狗的那群人内部也不可能冲突,冲突只可能发生在喜欢猫与喜欢狗的人之间,那么只要在发生冲突的人之间连边,计算一下最大点独立集就是答案了。对于一个二分图,最大点独立=N-最大匹配。
#include<cstdio> #include<cstring> #include<cmath> #include<vector> #include<queue> #include<algorithm> using namespace std; const int INF=0x7FFFFFFF; const int MAXN=505; int nx,ny; int g[MAXN][MAXN]; int cx[MAXN],cy[MAXN]; int mk[MAXN]; int N,M,P; char Lik[MAXN][50],Dis[MAXN][50]; void init() { memset(g,0,sizeof g); nx=P,ny=P; } int path(int u) { for(int v=1; v<=ny; v++) { if(g[u][v]&&!mk[v]) { mk[v]=1; if(cy[v]==-1||path(cy[v])) { cx[u]=v; cy[v]=u; return 1; } } } return 0; } int MaxMatch() { int res=0; memset(cx,-1,sizeof(cx)); memset(cy,-1,sizeof(cy)); for(int i=1; i<=nx; i++) { if(cx[i]==-1) { memset(mk,0,sizeof(mk)); res=res+path(i); } } return res; } bool Fail(int x,int y) { if(strcmp(Lik[x],Dis[y])==0) return true; if(strcmp(Lik[y],Dis[x])==0) return true; return false; } int main() { while(~scanf("%d%d%d",&N,&M,&P)) { init(); int tot=0; for(int i=1; i<=P; i++) scanf("%s%s",Lik[i],Dis[i]); for(int i=1; i<=P; i++) for(int j=1; j<i; j++) if(Fail(i,j)) { if(Lik[i][0]=='C') g[i][j]=1; else g[j][i]=1; } printf("%d ",P-MaxMatch()); } return 0; }