uva 10985 - Rings'n'Ropes( 最短路Folyd)

题目连接:uva 10985 - Rings'n'Ropes


题目大意:给出n和m,表示有n个戒指和m条绳子,每条绳子的长度为1,给出每根绳子连接的戒指,然在左右手各握住一个戒指,拉直,问说最多有多少个绳子被绷直。


解题思路:首先先用Floyd算法将每两个戒指之间的最短距离求出(因为向两端扯的时候,最大距离便是连接两个戒指的最短距离),然后枚举两枚戒指,找出中间所有的点(f[x][i] + f[i][y] == f[x][y]);然后在将两点之间所有的点枚举两点,只有这两点之间存在边,并且f[x][i] != f[x][j];


#include <stdio.h>
#include <string.h>

#define min(a,b) (a)<(b)?(a):(b)
#define max(a,b) (a)>(b)?(a):(b)

const int N = 150;
const int INF = 0x3f3f3f3f;

int n, m, ans, g[N][N], f[N][N];

void init() {
	int a, b;
	memset(g, 0, sizeof(g));
	memset(f, INF, sizeof(f));

	scanf("%d%d", &n, &m);

	for (int i = 0; i < m; i++) {
		scanf("%d%d", &a, &b);
		f[a][b] = f[b][a] = g[a][b] = g[b][a] = 1;
	}

	for (int i = 0; i < n; i++)
		f[i][i] = 0;
}

void Floyd() {
	for (int k = 0; k < n; k++)
		for (int i = 0; i < n; i++)
			for (int j = 0; j < n; j++)
				f[i][j] = min(f[i][j], f[i][k] + f[k][j]);
}

int solve() {
	int tmp, ans = 0;
	int c, s[N];

	for (int x = 0; x < n; x++) {
		for (int y = x + 1; y < n; y++) {

			if (f[x][y] == INF) continue;

			tmp = c = 0;
			memset(s, 0, sizeof(s));

			for (int i = 0; i < n; i++) if (f[x][i] + f[i][y] == f[x][y]) s[c++] = i;

			for (int i = 0; i < c; i++) {
				for (int j = i + 1; j < c; j++) {

					if (g[s[i]][s[j]] && f[x][s[i]] != f[x][s[j]]) tmp++;
				}
			}

			ans = max(ans, tmp);
		}
	}

	return ans;
}

int main () {
	int cas;
	scanf("%d", &cas);
	for (int i = 1; i <= cas; i++) {
		init();
		Floyd();
		printf("Case #%d: %d\n", i, solve() );
	}
	return 0;
}


你可能感兴趣的:(uva 10985 - Rings'n'Ropes( 最短路Folyd))