1014 Circles of Friends (35分)(C++)

A circle of friends is a network of friend relationships. If A is a friend of B, then B is considered a friend of A no matter B admits or not, and they are said to belong to the same circle. Here we assume that friendship is transitive, that is, if A is a friend of B, and B is a friend of C, then A is a friend of C and the three of them all belong to the same circle.

On the other hand, A is not so close to C as B is. We define the distance D(X, Y) between two friends X and Y as the minimum number of friends between them. For example, D(A, B) = 0, and D(C, A) = 1. The diameter of a friends circle is the maximum distance between any pair of friends in the circle.

Now given some people's relationships, you are supposed to find the number of friends circles and the circle with the largest diameter.

Input Specification:

Each input file contains one test case. For each case, the first line gives an integer N (2≤N≤1000), which is the total number of people involved, and hence they are numbered from 1 to N. Then N lines follow, each in the format:

k p​1​​ ... p​k​​

where k (0≤k<min(10,N)) is the number of friends and p​1​​ to p​k​​ (if k>0) are the friends' indices. The i-th line corresponds to the i-th person. All the numbers in a line are separated by spaces. It is guaranteed that no one is given as a friend of oneself.

Output Specification:

For each case, print in a line the number of friends circles, and the largest diameter, separated by exactly one space.

Sample Input:

17
2 15 12
1 17
2 16 9
1 8
4 10 13 15 14
0
2 11 14
1 4
2 2 3
2 13 11
2 15 7
2 1 14
2 5 15
0
0
1 3
1 2

Sample Output:

4 3

题目大意:划定朋友圈,只要A,B之间可能通过好友线联系起来,就是一个圈子的。现在要求有多少个朋友圈。另外A,B之间需要最短通过几个好友才能联系上为A,B之间的距离,现在还要求出这些人之间最大的距离。

解题思路:乍一看像是并查集的题目。但是对于距离的求解并查集就不起作用了,还得老老实实用BFS(理论上DFS也可以,不知道会不会超时,有兴趣的可以尝试一下)。本题思路可以参考甲级题目1021

这里思路是类似的,第一遍遍历的时候存储一下距离最大的那几个点,再次进行遍历的时候只要对这几个点进行BFS,计算与他们相距最大的距离即可!

代码:

#include<bits/stdc++.h>
using namespace std;
vector<set<int>> v;
set<int> lastlevel, anslevel;
bool visit[1005] = {0}, tempvisit[1005];
int n, k, temp, cnt = 0, ans = 0;
void BFS(int index){
	queue<int> q;
	vector<int> dis(n+1, 0);
	q.push(index);
	fill(tempvisit, tempvisit+1005, false);
	visit[index] = true;
	while(!q.empty()){
		temp = q.front();
		visit[temp] = true;
		tempvisit[temp] = true;
		q.pop();
		if(dis[temp]-1 > ans){
			lastlevel.clear();
			lastlevel.insert(temp);
			ans = dis[temp]-1;
		}
		else if(dis[temp] - 1 == ans)
			lastlevel.insert(temp);
		for(auto it = v[temp].begin(); it != v[temp].end(); it ++){
            if(!tempvisit[*it]){
                q.push(*it);
                tempvisit[*it] = true;
                dis[*it] = dis[temp]+1;
            }
        }
	}
} 
int main(){
    scanf("%d", &n);
    v.resize(n+1);
    for(int i = 1; i <= n; ++ i){
        scanf("%d", &k);
        for(int j = 0; j < k; ++ j){
            scanf("%d", &temp);
            v[i].insert(temp);
            v[temp].insert(i);
        }
    }
    for(int i = 1; i <= n; ++ i){
        if(visit[i])
        	continue;
        ++ cnt;
        BFS(i);
    }
    anslevel = lastlevel;
    fill(visit, visit+1005, false);
    for(auto it = anslevel.begin(); it != anslevel.end(); ++ it)
    	BFS(*it);
    printf("%d %d", cnt, ans);
} 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章