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

来源:互联网 发布:dm1016破解网络锁 编辑:程序博客网 时间:2024/06/05 19:37

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


原创粉丝点击