uva10985
题目链接请戳 这里
解题思路
先用Floyed算出最短路。
枚举任意点对,得到最短路上的所有点。去掉连接同一层次点的边就好了。
代码
#include<stdio.h> #include<string.h> #include<algorithm> #define N 140 #define INF 1e9 using namespace std; int d[N][N], a[N][N], s[N]; int n; void floyd() { for (int k = 0; k < n; k++) for (int i = 0; i < n; i++) for (int j = 0; j < n; j++) if (d[i][k] < INF && d[k][j] < INF) d[i][j] = min(d[i][k] + d[k][j], d[i][j]); } int main() { int t, c = 0; scanf("%d", &t); while (t--) { int m; scanf("%d%d", &n, &m); for (int i = 0; i < n; i++) for (int j = 0; j < n; j++) { d[i][j] = INF; a[i][j] = 0; if (i == j) { d[i][j] = 0; a[i][j] = 1; } } for (int i = 0; i < m; i++) { int x, y; scanf("%d%d", &x, &y); d[x][y] = d[y][x] = 1; a[x][y] = a[y][x] = 1; } //floyd预处理 floyd(); int maxn = 0; //枚举任意两点 for (int i = 0; i < n; i++) for (int j = i + 1; j < n; j++) if (i != j && d[i][j] != INF) { int tot = 0; //最短路上点的个数 int temp = 0; //当前这两点上绷紧的绳子数目 //找最短路上的点,注意最短可能有多条 for (int k = 0; k < n; k++) if (d[i][k] + d[k][j] == d[i][j]) s[tot++] = k; //枚举最短路上任意两点,去掉连接同一层次点的边 for (int x = 0; x < tot; x++) for (int y = x + 1; y < tot; y++) { if (a[s[x]][s[y]] == 1 && d[i][s[x]] != d[i][s[y]]) temp++; } maxn = max(maxn, temp); } printf("Case #%d: ", ++c); printf("%d\n", maxn); } return 0; }