您的位置:首页 > 其它

uva 10985(最短路径)

2014-11-20 21:57 477 查看
题意:有n个相同的环m个相同的绳索,每个绳索的两边可以各套一个环,给出了绳索两边套的环的编号,选两个环向两边将绳索尽力拉伸,问最多有几条绳索被绷直。

题解:很容易想出如果两个环之间有2条线,一条线有3条绳索,另一条线有4条绳索,那么一定是3条绳索长的线被拉直,那么最长也就有3条绳索被绷直,另一条线是松弛状态,因此是先找最短路(floyd算法),然后看任意两点间路径等于最短路的绳索一共有多少条(dfs)判断一条边是否是组成最短路的一条绳索,如果f[l][x] + g[x][y] +f[y][r] == 最短路(l是起点,r是终点,g[x][y]是判断的边),那么结果加一,选出最多的就是解。

#include <stdio.h>
#include <string.h>
#include <queue>
using namespace std;
const int N = 250;
const int INF = 0x3f3f3f3f;
int t, cases = 1, n, m, f

, vis

;
int g

, length, en, res;

void floyd() {
for (int k = 0; k < n; k++)
for (int i = 0; i < n; i++)
for (int j = 0; j < n; j++)
if (f[i][j] > f[i][k] + f[k][j])
f[i][j] = f[i][k] + f[k][j];
}

void dfs(int u, int l, int r) {
for (int i = 0; i < n; i++)
if (g[u][i] && f[l][u] + g[u][i] + f[i][r] == length && !vis[u][i]) {
vis[u][i] = vis[i][u] = 1;
res++;
dfs(i, l, r);
}
}

int main() {
scanf("%d", &t);
while (t--) {
scanf("%d%d", &n, &m);
memset(g, 0, sizeof(g));
memset(vis, 0, sizeof(vis));
for (int i = 0; i < N; i++)
for (int j = 0; j < N; j++)
if (i == j)
f[i][j] = 0;
else
f[i][j] = INF;
int a, b;
for (int i = 0; i < m; i++) {
scanf("%d%d", &a, &b);
f[a][b] = f[b][a] = 1;
g[a][b] = g[b][a] = 1;
}
floyd();
int l, r;
res = 0;
int maxx = -1;
for (int i = 0; i < n; i++)
for (int j = i + 1; j < n; j++) {
res = 0;
memset(vis, 0, sizeof(vis));
length = f[i][j];
dfs(i, i, j);
if (maxx < res)
maxx = res;
}
printf("Case #%d: %d\n", cases++, maxx);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  uva floyd