想看更多的解题报告: 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;
}