#include <stdio.h>
#define MAX_POINTS 101
#define INF 300000
int numOfPoints, numOfRoads;
int initialDist[MAX_POINTS][MAX_POINTS];
int shortestDist[MAX_POINTS][MAX_POINTS];
int pre[MAX_POINTS][MAX_POINTS];
int path[MAX_POINTS];
int num;
int getMin(int x, int y){
return x < y ? x : y;
}
int main(){
//freopen("input.txt", "r", stdin);
while (scanf("%d", &numOfPoints) != EOF){
if (numOfPoints == -1)
break;
int from, to;
for (from = 1; from <= numOfPoints; from++)
for (to = 1; to <= numOfPoints; to++){
initialDist[from][to] = shortestDist[from][to] = INF;
pre[from][to] = from;
}
scanf("%d", &numOfRoads);
int dist;
int i;
for (i = 1; i <= numOfRoads; i++){
scanf("%d%d%d", &from, &to, &dist);
initialDist[from][to] = shortestDist[from][to] = initialDist[to][from] = shortestDist[to][from] = getMin(dist, initialDist[from][to]);
}
int minLen = INF;
int pass;
for (pass = 1; pass <= numOfPoints; pass++){
//遍历所有环,from-> (因为最小环要求不经过相同的景点,所以走不包含pass的最短路,因为还没计算呢) -> to -> pass -> from
for (from = 1; from < pass; from++)
for (to = from + 1; to < pass; to++){
int routeLen = shortestDist[from][to] + initialDist[from][pass] + initialDist[pass][to];
if (routeLen < minLen){
minLen = routeLen;
int prePoint = to;
num = 0;
while (prePoint != from){
path[num++] = prePoint;
prePoint = pre[from][prePoint];
}
path[num++] = from;
path[num++] = pass;
}
}
for (from = 1; from <= numOfPoints; from++)
//需记录路径,不能对称优化
for (to = 1; to <= numOfPoints; to++)
if (shortestDist[from][pass] + shortestDist[pass][to] < shortestDist[from][to]){
shortestDist[from][to] = shortestDist[from][pass] + shortestDist[pass][to];
pre[from][to] = pre[pass][to];
}
}
if (minLen == INF)
printf("No solution.\n");
else {
for (i = 0; i < num; i++)
printf("%d ", path[i]);
printf("\n");
}
}
return 0;
}
POJ 1734 Sightseeing Trip (最小环)
最新推荐文章于 2020-08-01 11:14:42 发布