蓝桥杯算法提高Degrees of Separation解题报告---并查集 & Floyd两点之间最短路

版权声明:转载请注明出处:https://blog.csdn.net/qq1013459920 https://blog.csdn.net/qq1013459920/article/details/87955083

                                 算法提高 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;
}

猜你喜欢

转载自blog.csdn.net/qq1013459920/article/details/87955083