团体程序设计天梯赛 L2-024. 部落

L2-024. 部落

时间限制
120 ms
内存限制
65536 kB
代码长度限制
8000 B
判题程序
Standard
作者
陈越

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

输入格式:

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

K P[1] P[2] ... P[K]

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

之后一行给出一个非负整数Q(<= 104),是查询次数。随后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
#include<iostream>
#include<set>
#include<algorithm>
#include<vector>
#include<string>
using namespace std;

vector<int>  v(10002);

int find(int n)
{
  if(v[n]==n)
    return n;
  v[n]=find(v[n]);
  return v[n];
}

int main()
{
  set<int> s1;
  set<int> s2;
  for(int i=0;i<v.size();i++)
  {
    v[i]=i;
  }
  int n;
  cin>>n;
  for(int i=0;i<n;i++)
  {
    int k;
    cin>>k;
    vector<int> line(k);
    for(int i=0;i<k;i++)
    {
      cin>>line[i];
      s1.insert(line[i]);
    }
    int mark=find(line[0]);
    for(int i=1;i<k;i++)
    {
      if(line[i]!=v[line[i]])
      {
        v[find(line[i])]=mark;
      }
      else
        v[line[i]]=mark;
    }
  }
  set<int>::iterator iter;
  for(iter=s1.begin();iter!=s1.end();iter++)
  {
    find(*iter);
    s2.insert(v[*iter]);
  }
  cout<<s1.size()<<" "<<s2.size()<<endl;
  int q;
  cin>>q;
  for(int i=0;i<q;i++)
  {
    int d1,d2;
    cin>>d1>>d2;
    if(find(d1)==find(d2))
    {
      cout<<"Y"<<endl;
    }
    else
    {
      cout<<"N"<<endl;
    }
  }
  return 0;
}
阅读更多
想对作者说点什么?

博主推荐

换一批

没有更多推荐了,返回首页