1014 Circles of Friends (35)(35 分)
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 p1 … pk
where k (0 <= k < min(10, N)) is the number of friends and p1 to pk (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
手速题。求一个图中连通分量的个数和所有连通分量中最短路径的最大值-1。
求连通分量并查集是最好的做法
求最短路径的最大值我是跑了n次堆优化dj算法,算出所有可能值输出。
实际上是因为是无权图。直接用queue跑bfs就行了。不用dj算法
我这样做就是n^2*logn的,也是能AC的。
实际n^2就行了。。。
#include <bits/stdc++.h>
using namespace std;
vector<int> g[1005];
int fa[1005];
int dis[1005][1005];
bool visit[1005];
int jtfind(int x)
{
return fa[x] == x ? x : fa[x] = jtfind(fa[x]);
}
struct node{
int p, w;
node(int a, int b):p(a), w(b){}
bool operator< (const node& b) const
{
return w > b.w;
}
};
priority_queue<node> sup;
void dijkstra(int start)
{
memset(dis[start], 0x3f, sizeof(dis[start]));
dis[start][start] = 0;
sup.push(node(start, 0));
while (!sup.empty())
{
node front = sup.top();
sup.pop(); int tempv = front.p;
if (visit[tempv]) continue;
visit[tempv] = true;
for (int i = 0; i < g[tempv].size(); i++)
{
int p = g[tempv][i];
if (!visit[p] && dis[start][tempv]+1 < dis[start][p])
{
dis[start][p] = dis[start][tempv]+1;
sup.push(node(p, dis[start][p]));
}
}
}
}
set<int> res;
int main(void)
{
int n;
scanf("%d", &n);
int i, j;
for (i = 1; i <= n; i++) fa[i] = i;
for (i = 1; i <= n; i++)
{
int k;
scanf("%d", &k);
while (k--)
{
int temp;
scanf("%d", &temp);
if (find(g[i].begin(), g[i].end(), temp) == g[i].end())
{
g[i].push_back(temp);
}
if (find(g[temp].begin(), g[temp].end(), i) == g[temp].end())
{
g[temp].push_back(i);
}
}
}
for (i = 1; i <= n; i++)
{
for (j = 0; j < g[i].size(); j++)
{
if (jtfind(i) == jtfind(g[i][j])) continue;
fa[jtfind(g[i][j])] = i;
}
}
for (i = 1; i <= n; i++)
{
res.insert(jtfind(i));
}
for (i = 1; i <= n; i++)
{
memset(visit, false, sizeof(visit));
dijkstra(i);
}
int ans = 1;
int a, b;
for (i = 1; i <= n; i++)
{
for (j = 1; j <= n; j++)
{
if (dis[i][j] != 0x3f3f3f3f)
{
ans = max(ans, dis[i][j]);
}
}
}
cout << res.size() << " " << ans-1;
}