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

179 篇文章 0 订阅
36 篇文章 0 订阅

题目连接: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;
}


  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值