The input contains several data sets in text format. Each data set represents one set of subjects of the study, with the following description:
the number of students
the description of each student, in the following format
student_identifier:(number_of_romantic_relations) student_identifier1 student_identifier2 student_identifier3 ...
or
student_identifier:(0)
The student_identifier is an integer number between 0 and n-1 (n <=500 ), for n subjects.
the number of students
the description of each student, in the following format
student_identifier:(number_of_romantic_relations) student_identifier1 student_identifier2 student_identifier3 ...
or
student_identifier:(0)
The student_identifier is an integer number between 0 and n-1 (n <=500 ), for n subjects.
For each given data set, the program should write to standard output a line containing the result.
7 0: (3) 4 5 6 1: (2) 4 6 2: (0) 3: (0) 4: (2) 0 1 5: (1) 0 6: (2) 0 1 3 0: (2) 1 2 1: (1) 0 2: (1) 0
5 2
题意:在一群男女同学之间存在”浪漫关系”,且该关系只存在于男同学与女同学之间.现在给出你比如2号学生与4号学生有浪漫关系(但是没给出你到底2号是男同学还是4号是男同学).给出所有的关系,要你求出一个由学生构成的集合,满足该集合中任意两人都不存在”浪漫关系”。
思路:最大独立集。遇到这种求满足一定限制条件的所有集合中元素个数最大的问题,都可以尝试想最大独立集,且 需要分析一下是否能构成二分图,而且可以带着构建二分图的目的去想思路。
题目给的条件没有男女,所以可以将所有条件分解分成男和女两个集合,然后构建二分图,再进行求最大独立集即可。但是发现分解成两个集合不是很好操作,至少并查集就解决不了。
/*
最大独立集m=总点数n - 最大匹配数
*/
#include<stdio.h>
#include<string.h>
#include<vector>
using namespace std;
const int N = 510;
int match[N],vis[N];
vector<int>G[N];
int n;
void init(){
for(int i=0;i<=n;i++)
G[i].clear();
}
int Find(int x){
for(int i=0;i<G[x].size();i++){
int u=G[x][i];
if(!vis[u]){
vis[u]=1;
if(match[u]==-1||Find(match[u])){
match[u]=x;
return 1;
}
}
}
return 0;
}
int solve(){
memset(match,-1,sizeof(match));
int ans=0;
for(int i=0;i<n;i++){
memset(vis,0,sizeof(vis));
ans+=Find(i);
}
return ans;
}
int main(){
while(scanf("%d",&n)!=EOF){
init();
for(int i=0;i<n;i++){
int a,m;
scanf("%d: (%d)",&a,&m);
for(int j=0;j<m;j++){
int b;
scanf("%d",&b);
G[a].push_back(b);
}
}
int sum=solve();
printf("%d\n",n-sum/2);
}
return 0;
}