la3415(最大独立集)
最大独立集与最小顶点覆盖互补
#include<cstdio> #include<string> #include<iostream> #include<cstring> #include<cmath> #include<algorithm> using namespace std; struct my{ int v; int next; }; struct student{ int high; int num; string music; string sports; }; const int maxn=1000+10; int n,m; int adj[maxn]; my bian[1000000]; int left1[maxn]; int t[maxn]; int fa; void myinsert(int u,int v){ bian[++fa].v=v; bian[fa].next=adj[u]; adj[u]=fa; } void init(){ memset(bian,0,sizeof(bian)); memset(adj,0,sizeof(adj)); fa=0; } bool cmp(student a,student b){ if(abs(a.high-b.high)<=40 && a.music==b.music && a.sports!=b.sports) return true; return false; } bool match(int u){ for (int i=adj[u];i;i=bian[i].next){ int v=bian[i].v; if(!t[v]){ t[v]=true; if(!left1[v] || match(left1[v])){ left1[v]=u; return true; } } } return false; } int KM(){ memset(left1,0,sizeof(left1)); int ans=0; for (int i=1;i<=n;i++){ memset(t,0,sizeof(t)); if(match(i)) ans++; } return ans; } int main(){ int t; int top1; int top2; scanf("%d",&t); while(t--){ student boy[maxn]; student girl[maxn]; init(); top1=0; top2=0; int l; scanf("%d",&l); char male; int high; for (int p=1;p<=l;p++){ cin>>high>>male; if(male=='M'){ boy[++top1].high=high; boy[top1].num=p; cin>>boy[top1].music>>boy[top1].sports; } else { girl[++top2].high=high; girl[top2].num=p; cin>>girl[top2].music>>girl[top2].sports; } } n=top1; m=top2; for (int i=1;i<=n;i++){ for (int j=1;j<=m;j++){ if(cmp(boy[i],girl[j])){ myinsert(i,j); } } } /* for (int i=1;i<=n;i++){ printf("%d ",i); for (int j=adj[i];j!=-1;j=bian[j].next){ printf("%d ",bian[j].v); } printf("\n");*/ printf("%d\n",top1+top2-KM()); } return 0; }