想看更多的解题报告: http://blog.csdn.net/wangjian8006/article/details/7870410
转载请注明出处:http://blog.csdn.net/wangjian8006
题目大意:有n个学生,每个学生都和一些人又关系,现在要你找出最大的人数,使得这些人之间没关系
解题思路:裸的最大独立集,最大独立集=点数-最大匹配数
这里注意因为是两两匹配,所以求出的匹配值要除上个2
优化了几下,时间不断减少
/* Memory 1164K Time 3844MS */ #include <iostream> using namespace std; #define MAXV 505 int map[MAXV][MAXV]; int n; int link[MAXV],use[MAXV]; bool dfs(int x){ int i,j; for(i=0;i<n;i++){ if(!use[i] && map[x][i]){ use[i]=1; if(link[i]==-1 || dfs(link[i])){ link[i]=x; return true; } } } return false; } int hungary(){ int num=0,i; memset(link,-1,sizeof(link)); for(i=0;i<n;i++){ memset(use,0,sizeof(use)); if(dfs(i)) num++; } return n-num/2; } int main(){ int i,j,cnt; int a,b; while(~scanf("%d",&n)){ memset(map,0,sizeof(map)); for(i=0;i<n;i++){ scanf("%d: (%d)",&a,&cnt); for(j=0;j<cnt;j++){ scanf("%d",&b); map[a][b]=1; } } printf("%d\n",hungary()); } return 0; }
============================================================================================
/* Memory 412K Time 1391MS */ #include <iostream> using namespace std; #define MAXV 500 int vx[MAXV],vy[MAXV],n; bool map[MAXV][MAXV]; bool use[MAXV]; bool dfs(int x){ int i; for(i=0;i<n;i++){ if(map[x][i] && !use[i]){ use[i]=1; if(vy[i]==-1 || dfs(vy[i])){ vy[i]=x; vx[x]=i; return true; } } } return false; } int hungary(){ int i,num=0,j; memset(vx,-1,sizeof(vx)); memset(vy,-1,sizeof(vy)); for(i=0;i<n;i++){ if(vx[i]==-1){ for(j=0;j<n;j++) use[j]=0; if(dfs(i)) num++; } } return n-num/2; } int main(){ int i,j,cnt; int a,b; while(~scanf("%d",&n)){ memset(map,0,sizeof(map)); for(i=0;i<n;i++){ scanf("%d: (%d)",&a,&cnt); for(j=0;j<cnt;j++){ scanf("%d",&b); map[a][b]=1; } } printf("%d\n",hungary()); } return 0; }
================================================================================================
/* Memory 188K Time 438MS */ #include <iostream> using namespace std; #define MAXV 500 #define MAXM 20000 typedef struct{ int t,next; }Edge; Edge edge[MAXM]; int vx[MAXV],vy[MAXV],n,edge_sum; int headlist[MAXV]; bool use[MAXV]; bool dfs(int x){ int i,t; for(i=headlist[x];i!=-1;i=edge[i].next){ t=edge[i].t; if(!use[t]){ use[t]=1; if(vy[t]==-1 || dfs(vy[t])){ vy[t]=x; vx[x]=t; return true; } } } return false; } int hungary(){ int i,num=0,j; memset(vx,-1,sizeof(vx)); memset(vy,-1,sizeof(vy)); for(i=0;i<n;i++){ if(vx[i]==-1){ for(j=0;j<n;j++) use[j]=0; if(dfs(i)) num++; } } return n-num/2; } void add(int a,int b){ edge[edge_sum].t=b; edge[edge_sum].next=headlist[a]; headlist[a]=edge_sum++; } int main(){ int i,j,cnt; int a,b; while(~scanf("%d",&n)){ edge_sum=0; memset(headlist,-1,sizeof(headlist)); for(i=0;i<n;i++){ scanf("%d: (%d)",&a,&cnt); for(j=0;j<cnt;j++){ scanf("%d",&b); add(a,b); } } printf("%d\n",hungary()); } return 0; }
=================================================================================================
/* Memory 184K Time 422MS */ #include <iostream> using namespace std; #define MAXV 500 #define MAXM 20000 typedef struct{ int t,next; }Edge; Edge edge[MAXM]; int link[MAXV],n,edge_sum; int headlist[MAXV]; bool use[MAXV]; bool dfs(int x){ int i,t; for(i=headlist[x];i!=-1;i=edge[i].next){ t=edge[i].t; if(!use[t]){ use[t]=1; if(link[t]==-1 || dfs(link[t])){ link[t]=x; return true; } } } return false; } int hungary(){ int num=0,i; memset(link,-1,sizeof(link)); for(i=0;i<n;i++){ memset(use,0,sizeof(use)); if(dfs(i)) num++; } return n-num/2; } void add(int a,int b){ edge[edge_sum].t=b; edge[edge_sum].next=headlist[a]; headlist[a]=edge_sum++; } int main(){ int i,j,cnt; int a,b; while(~scanf("%d",&n)){ edge_sum=0; memset(headlist,-1,sizeof(headlist)); for(i=0;i<n;i++){ scanf("%d: (%d)",&a,&cnt); for(j=0;j<cnt;j++){ scanf("%d",&b); add(a,b); } } printf("%d\n",hungary()); } return 0; }