L2-4 部落 (25 分)

在一个社区里,每个人都有自己的小圈子,还可能同时属于很多不同的朋友圈。我们认为朋友的朋友都算在一个部落里,于是要请你统计一下,在一个给定社区中,到底有多少个互不相交的部落?并且检查任意两个人是否属于同一个部落。

输入格式:

输入在第一行给出一个正整数N(≤),是已知小圈子的个数。随后N行,每行按下列格式给出一个小圈子里的人:

⋯ [

其中K是小圈子里的人数,[(,)是小圈子里每个人的编号。这里所有人的编号从1开始连续编号,最大编号不会超过1。

之后一行给出一个非负整数Q(≤),是查询次数。随后Q行,每行给出一对被查询的人的编号。

输出格式:

首先在一行中输出这个社区的总人数、以及互不相交的部落的个数。随后对每一次查询,如果他们属于同一个部落,则在一行中输出Y,否则输出N

输入样例:

4
3 10 1 2
2 3 4
4 1 5 7 8
3 9 6 4
2
10 5
3 7

输出样例:

10 2
Y
N


 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<set>
 5 #include<algorithm>
 6 using namespace std;
 7 typedef long long ll;
 8 const int amn=1e4+5;
 9 
10 int pre[amn];
11 
12 set<int> js;
13 
14 void init(int n)
15 {
16     for(int i=1;i<=n;i++)
17     {
18         pre[i]=i;
19     }
20 }
21 int find_pre(int x)
22 {
23     if(pre[x]==x)return x;
24     return pre[x]=find_pre(pre[x]);
25 }
26 void Union(int i,int j)
27 {
28     i=find_pre(i);
29     j=find_pre(j);
30     if(i==j)return;
31     else
32     {
33         pre[i]=j;
34     }
35 }
36 int is(int i,int j)
37 {
38     return find_pre(i)==find_pre(j);
39 }
40 
41 
42 int main()
43 {
44     int n,k,in;
45     init(amn-5);
46     cin>>n;
47     for(int v=1; v<=n; v++)
48     {
49         cin>>k;
50         int in[k+5];
51         for(int i=1;i<=k;i++)
52         {
53             cin>>in[i];
54             js.insert(in[i]);
55             if(i>1)
56             {
57                 Union(in[i],in[i-1]);
58             }
59         }
60     }
61     int tot=js.size(),con=0,q,qa,qb;
62     for(int i=1;i<=tot;i++)
63     {
64         if(pre[i]==i)con++;
65     }
66     cout<<tot<<" "<<con<<endl;
67     cin>>q;
68     while(q--)
69     {
70         cin>>qa>>qb;
71         if(is(qa,qb))cout<<"Y\n";
72         else cout<<"N\n";
73     }
74 }

 

posted @ 2019-03-26 20:51  Railgun000  阅读(377)  评论(0编辑  收藏  举报