In a community where everyone has their own small circle, it may also belong to many different circle of friends. We believe that friends of friends are counted in a tribe, so to ask you to look at statistics in a given community, in the end how many disjoint tribe? And to check whether any two people belong to the same tribe.
Input formats:
A first input line of a given positive integer NNN (≤104 \ 10 ^ 4≤ . 1 0 . 4 ), the number of known small circle. ThenNNN rows, each row is given a small group of people in the following format:
KKK P [1] P [1]P[1] P[2]P[2]P[2] ⋯\cdots⋯ P[K]P[K]P[K]
Which KKK is the number of the inner circle,P [i] P [i]P[i](i=1,⋯,Ki=1, \cdots , Ki = 1 , ⋯ , K ) is a small circle of everyone's number. Here all numbered consecutively numbered starting with 1, the maximum number will not exceed10410 ^ 4104。
After the line is given a non-negative integer QQQ (≤104 \ 10 ^ 4≤ 1 0 4 ), is the number of queries. ThenQQQ lines, each line gives the number of people being queried couple.
Output formats:
First output of this total number of communities, as well as the number of disjoint tribe in a row. Then for each query, if they belong to the same tribe, the output in a row Y
, otherwise the output N
.
Sample input:
4
3 10 1 2
2 3 4
4 1 5 7 8
3 9 6 4
2
10 5
3 7
Sample output:
10 2
Y
N
Two test points timeout
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashSet;
import java.util.Set;
import java.util.StringTokenizer;
//** Class for buffered reading int and double values *//*
class Reader {
static BufferedReader reader;
static StringTokenizer tokenizer;
// ** call this method to initialize reader for InputStream *//*
static void init(InputStream input) {
reader = new BufferedReader(new InputStreamReader(input));
tokenizer = new StringTokenizer("");
}
// ** get next word *//*
static String next() throws IOException {
while (!tokenizer.hasMoreTokens()) {
// TODO add check for eof if necessary
tokenizer = new StringTokenizer(reader.readLine());
}
return tokenizer.nextToken();
}
static boolean hasNext()throws IOException {
return tokenizer.hasMoreTokens();
}
static String nextLine() throws IOException{
return reader.readLine();
}
static char nextChar() throws IOException{
return next().charAt(0);
}
static int nextInt() throws IOException {
return Integer.parseInt(next());
}
static float nextFloat() throws IOException {
return Float.parseFloat(next());
}
}
public class Main {
private static int[]a;
public static void main(String[] args) throws IOException {
Reader.init(System.in);
int n = Reader.nextInt();
Set<Integer>set = new HashSet<Integer>();
a = new int[10001];
for (int i = 1; i < a.length; i++) {
a[i] = i;
}
input(n,set);
int q = Reader.nextInt();
int cnt = 0;
for (int i = 1; i <= set.size(); i++) {
if(a[i]==i)cnt++;
}
System.out.println(set.size()+" "+cnt);
for (int i = 0; i < q; i++) {
int node1 = Reader.nextInt();
int node2= Reader.nextInt();
if (find(node1)==find(node2)) {
System.out.println("Y");
}else {
System.out.println("N");
}
}
}
static void input(int n, Set<Integer> set) throws IOException {
for (int i = 0; i < n; i++) {
int k = Reader.nextInt();
int a = Reader.nextInt();
set.add(a);
for (int j = 1; j < k; j++) {
int b = Reader.nextInt();
set.add(b);
join(a,b);
}
}
}
static int find(int x) // 查找根节点
{
int r = x;
while (a[r] != r) // 返回根节点 r
r = a[r];
int i = x, j;
while (i != r) // 路径压缩
{
j = a[i]; // 在改变上级之前用临时变量 j 记录下他的值
a[i] = r; // 把上级改为根节点
i = j;
}
return r;
}
static void join(int x, int y) // 判断x y是否连通,
// 如果已经连通,就不用管了 如果不连通,就把它们所在的连通分支合并起,
{
int fx = find(x), fy = find(y);
if (fx != fy)
a[fx] = fy;
}
}