//1356K 172MS G++
#include <stdio.h>
#include <string.h>
#define NODE_MAX 505
int map[NODE_MAX][NODE_MAX];
int key[NODE_MAX];
int visited[NODE_MAX];
int nodeNum;
#define INF 999999
void solve() {
long distanceSum = 0;
int maxDistance = -INF;
for (int i = 0; i < nodeNum; i++) {
key[i] = INF;
visited[i] = 0;
}
key[0] = 0; // begin from 0
for (int i = 1; i <= nodeNum; i++) {
int minId = -1;
int minDistance = INF;
for (int j = 0; j < nodeNum; j++) {
if (!visited[j]) {
if (minDistance > key[j]) {
minId = j;
minDistance = key[j];
}
}
}
// minId Node is choosed
visited[minId] = 1;
distanceSum += minDistance;
maxDistance = maxDistance > minDistance ? maxDistance: minDistance;
for (int j = 0; j < nodeNum; j++) { // update minId's adjaency node
if (!visited[j] && map[minId][j] > 0) {
key[j] = key[j] < map[minId][j] ? key[j] : map[minId][j];
}
}
}
// printf("%ld %d\n", distanceSum, maxDistance);
printf("%d\n", maxDistance);
}
int main() {
int caseNum;
scanf("%d", &caseNum);
for (int i = 0; i < caseNum; i++) {
memset(map, 0, sizeof(map));
memset(key, 0, sizeof(key));
memset(visited, 0, sizeof(visited));
scanf("%d", &nodeNum);
for (int j = 0; j < nodeNum; j++) {
for (int k = 0; k < nodeNum; k++) {
int distance;
scanf("%d", &distance);
map[j][k] = distance;
}
}
solve();
}
}
最小生成树基本题,没啥说的.
只是要注意题目要求的是最小生成树里最长的那一段path的长度,一开始看错贡献了次WA.
这个长度也很好求,就在Prim算法每次取新的边的时候根据大小更新就可以了。
不过,其实有个问题的,那就是一个图其实有可能会有多个最小生成树的。
Prim最后得到的只是其中一个,而这个树的最长path不一定就是所有生成树的最长path。
(不过也有可能是个伪问题,因为有可能不同树只是每个path的长度顺序不一样, 比如树1: 1, 3 ,5, 树2: 3, 5, 1)
还要好好看看这部分的原理.
写Prim的时候老跟BellmanFord算法混淆,经常少循环一次,mark一下.
买一送一: 1258 代码基本不用改,输出总长度就OK,注意是多个case, 检测scanf EOF.