POJ 1734 Sightseeing trip

/*
第一次用扩展的Floyd来寻找最小代价环
*/
#include <iostream> #define MAX_N 105 #define MAX_VAL 666666666 using namespace std; int N, M, minLen; int weight[MAX_N + 1][MAX_N + 1]; int graph[MAX_N + 1][MAX_N + 1]; int pre[MAX_N + 1][MAX_N + 1]; int path[MAX_N + 1], plen; void init() { int i, j; for(i = 1; i <= N; i++) { for(j = 1; j <= N; j++) { graph[i][j] = weight[i][j] = MAX_VAL; pre[i][j] = -1; if(i == j) weight[i][j] = graph[i][j] = 0; } } minLen = MAX_VAL; } void getRes(int i, int j) { if(pre[i][j] != -1) getRes(i, pre[i][j]); path[plen++] = j; } void floyd() { int i, j, k; for(k = 1; k <= N; k++) { /* 比普通Floyd多出来的部分,主要利用到的原理是当处理到k时,所有以1 --- k - 1为中间结点的最短路径 都已经确定,则这时候的环为【i到j(1 < i, j <= k - 1)的最短路径】 + 边【i, k】 + 边【k, j】 遍历所有的i, j找到上述式子的最小值即位k下的最小代价环 */ for(i = 1; i <= k - 1; i++) { for(j = i + 1; j <= k - 1; j++) { int temp = graph[i][j] + weight[i][k] + weight[j][k]; if(temp < minLen) { minLen = temp; plen = 0; getRes(i, j); path[plen++] = k; } } } ///////////////////////////////////// for(i = 1; i <= N; i++) { for(j = 1; j <= N; j++) { if(i == 3 && j == 2) { int a = 2; } int dij = graph[i][j]; int dik = graph[i][k]; int dkj = graph[k][j]; if(dij > dik + dkj) { graph[i][j] = dik + dkj; pre[i][j] = pre[k][j]; } } } } } int main() { int i, from, to, w; scanf("%d%d", &N, &M); init(); for(i = 1; i <= M; i++) { scanf("%d%d%d", &from, &to, &w); if(w < graph[from][to]) { graph[from][to] = graph[to][from] = w; weight[from][to] = weight[to][from] = w; } pre[from][to] = from; pre[to][from] = to; } floyd(); if(minLen == MAX_VAL) printf("No solution./n"); else { for(i = 0; i < plen; i++) printf("%d ", path[i]); printf("/n"); } return 0; } 

你可能感兴趣的:(Graph,扩展,Path)