算法提高 Degrees of Separation
问题描述
在我们联系日益紧密的世界里,人们推测每个人和其他人的分离度不超过六(六度分离)。在这个问题里,你需要写一个程序来找出人们的关系网络中最大的分离度。
对于任意两个人,他们的分离度是联系两个人需要经过的最小的关系数。对于一个关系网络,最大的分离度是网络中任意两人的分离度的最大值。如果一个网络中有两个人没有通过关系链连接起来,这个网络是不连通的。
如下图所示,一个网络可以用一些连接两个人的对称关系来描述。一条线段表示两个人之间有联系。网络A描述了一个分离度最大值为2的网络,网络B没有连通。
输入格式
输入包含多组描述关系网络的数据,对于每组数据,第一行有两个数P,表示网络中人的数目,和R,关系的对数。接下来一行是R个关系。每个关系用两个字符串表示,代表网络中有关系的两个人的名字。每个名字是不同的,并且中间没有空格。因为一个人可能和多个人有联系,一个名字可能在一组数据中出现多次。
最后以一行两个0表示结束。
输出格式
对于每个网络,输出网络中最大的分离度。如果这个网络是不连通的,输出DISCONNECTED。每一个网络输出后再输出一个回车。按照样例输出中的格式输出。
样例输入
4 4
Ashok Kiyoshi Ursala Chun Ursala Kiyoshi Kiyoshi Chun
4 2
Ashok Chun Ursala Kiyoshi
6 5
Bubba Cooter Ashok Kiyoshi Ursala Chun Ursala Kiyoshi Kiyoshi Chun
0 0
样例输出
Network 1: 2
Network 2: DISCONNECTED
Network 3: DISCONNECTED
数据规模和约定
30%的数据2<=P<=15
100%的数据2<=P<=50,R>=1
并查集判断是否构成连通图,Flody算法求网络中最大的分离度(即所有两点之间最短距离中的最大值)
AC Code:
#include <iostream>
#include <cstring>
#include <queue>
#include <stack>
#include <cstdio>
#include <string>
#include <cstring>
#include <cmath>
#include <vector>
#include <algorithm>
#include <map>
#include <set>
#define Mod 1000000007
#define INF 0x3f3f3f3f
#define lson l, m, rt << 1
#define rson m + 1, r, rt << 1 | 1
#define eps 1e-8
#define lowbit(x) (x&-x);
typedef long long ll;
using namespace std;
static const int MAX_N = 1e5 + 5;
const double pi = acos(-1);
int dis[55][55]; //两点间距离
int pre[55]; //并查集前驱
void init() {
for (int i = 1; i < 55; i++) {
pre[i] = i;
for (int j = 1; j < 55; j++) {
dis[i][j] = (i == j ? 0 : INF);
}
}
}
int Find(int x) {
if (pre[x] != x) {
pre[x] = Find(pre[x]);
}
return pre[x];
}
void Union(int x, int y) {
int fx = Find(x), fy = Find(y);
if (fx != fy) {
pre[fx] = fy;
}
}
int main(){
int P, R;
int cas = 0;
while (scanf("%d%d", &P, &R) != EOF) {
if (P == 0 && R == 0) break;
init();
map<string, int>mps; //标记英文名
int cnt = 0; //编号
for (int i = 0; i < R; i++) {
string s1, s2;
cin >> s1 >> s2;
if (!mps[s1]) {
mps[s1] = ++cnt;
}
if (!mps[s2]) {
mps[s2] = ++cnt;
}
Union(mps[s1], mps[s2]);//合并
dis[mps[s1]][mps[s2]] = dis[mps[s2]][mps[s1]] = 1;
}
/*floyd算法*/
for (int k = 1; k <= P; k++) {
for (int i = 1; i <= P; i++) {
for (int j = 1; j <= P; j++) {
dis[i][j] = min(dis[i][j], dis[i][k] + dis[k][j]);
}
}
}
int sum = 0;
/*是否构成连通图*/
for (int i = 1; i <= P; i++) {
if (pre[i] == i) {
sum++;
}
}
if (sum == 1) {
int maxl = -INF;
/*连通图中任意两点最短距离中的最大值*/
for (int i = 1; i <= P; i++) {
for (int j = 1; j <= P; j++) {
if (dis[i][j] < INF) {
maxl = max(dis[i][j], maxl);
}
}
}
printf("Network %d: %d\n", ++cas, maxl);
}
else {
printf("Network %d: DISCONNECTED\n", ++cas);
}
putchar('\n');
}
return 0;
}