The students in Kim��s class did a popularity vote to determine who were popular in the class. Each student was asked to write down the ID numbers of at most three students, except himself/herself, whom he or she liked. After the vote was over and popular students were chosen, Kim, looking at the vote result, was curious to solve the following math question: What was the largest core?
A set of students is called a core if every student in the set
- voted,
- liked some students in it but no one outside it, and
- was liked by some one in it.
More formally, each student will be represented by his or her student ID number from {1, 2, ... , N}, where the class has N students. For example, the table below shows the result of a vote by 12 students in Kim��s class.
Student number | The numbers written down |
1 | 4, 8 |
2 | 9, 12, 3 |
4 | 8 |
5 | 1, 6 |
6 | 5 |
7 | 8 |
8 | 1 |
10 | 8, 7, 6 |
12 | 10 |
Students 3, 9, and 11 were absent from school and did not vote, so they do not appear in the left column of the table.
Kim found the set {1, 4, 5, 6, 8} to be a core; every student in it voted, liked some students in it but not outside it, and was liked by some one in it. More specifically, 1 liked {4, 8}, 4 liked {8}, 5 liked {1, 6}, 6 liked {5}, and 8 liked {1}. They collectively liked {4, 8, 1, 6, 5}, which are themselves. The number of students in this set is five. {1, 4, 8} is also a core, but it is smaller. As a matter of fact, no core with six or more students is possible from the table. Thus, the size of the largest core of the vote result above is five.
Write a program to find the size of the largest core of a vote result.
Input
The input consists of T test cases. The number of test cases (T) is given on the first line of the input file. The first line of each test case contains two integers N and M, where N (1 <= N <= 10000) is the number of students in the class, and M is the number of students who voted. Each of the following M lines is to begin with an integer i representing a student ID number in {1, 2, ... , N}, which is to be followed by an integer Ni (1 <= Ni <= 3) Ni representing the number of students written down by student i, which is to be followed in turn by a sequence of Ni integers representing the ID numbers written down by student i.
Output
Print exactly one line for each test case. The line is to contain an integer that is the size of the largest core. The following shows sample input and output for two test cases.
Sample Input
1 12 9 1 2 4 8 2 3 9 12 3 4 1 8 5 2 1 6 6 1 5 7 1 8 8 1 1 10 3 8 7 6 12 1 10
Sample Output
5
题目大意:给定一些人的投票,表示他喜欢哪些人。求满足条件的集合中最多有多少人。
要求:对于集合里的每个人,1:他必须投过票,2:他喜欢的人必须在集合里,3:集合里有人喜欢他
分析:先拓扑一次,不断把入度为0的点(即没有人喜欢)删掉,在dfs一次,把没有投过票的以及喜欢他们的人删掉,最后求剩下的人中能连通的最大值
#include<cstdio>
#include<stack>
#include<vector>
using namespace std;
const int N=10002;
vector<int> g[N],og[N];
int in_d[N],out_d[N],n;
bool vis[N];
void Top(){
int i,u,v;
stack<int> S;
while(!S.empty())S.pop();
for(i=1;i<=n;i++){
if(in_d[i]==0)S.push(i),vis[i]=1;
}
while(!S.empty()){
u=S.top(),S.pop();
for(i=0;i<g[u].size();i++){
v=g[u][i];
in_d[v]--;
if(in_d[v]==0)S.push(v),vis[v]=1;
}
}
}
void dfs(int u){
vis[u]=1;
for(int i=0;i<og[u].size();i++)if(!vis[og[u][i]])dfs(og[u][i]);
}
int cal(int u){
int i,v,res=1;
vis[u]=1;
for(i=0;i<g[u].size();i++){
v=g[u][i];
if(!vis[v])res+=cal(v);
}
for(i=0;i<og[u].size();i++){
v=og[u][i];
if(!vis[v])res+=cal(v);
}
return res;
}
int main(){
int T,m,i,j,k;
scanf("%d",&T);
while(T--){
scanf("%d%d",&n,&m);
for(i=1;i<=n;i++){
g[i].clear();og[i].clear();
in_d[i]=out_d[i]=0;
vis[i]=0;
}
while(m--){
scanf("%d%d",&i,&j);
while(j--){
scanf("%d",&k);
g[i].push_back(k);
og[k].push_back(i);
in_d[k]++,out_d[i]++;
}
}
Top();
for(i=1;i<=n;i++)if(out_d[i]==0)dfs(i);
int ans=0,tmp;
for(i=1;i<=n;i++)if(!vis[i]){
tmp=cal(i);
if(ans<tmp)ans=tmp;
}
printf("%d\n",ans);
}
return 0;
}