#include using namespace std; const int N = 110; #define INF 0x3f3f3f3f /** 分析:模板题,理解floyd 的在 i , j 路径中没有包含k(因为此时k未用来更新),即可写出最小环 */ int n, m; int g[N][N]; int dis[N][N]; // dp结果数组 int path[N][N]; int ans[N]; int cnt; int res = INF; void floyd() { for (int k = 1; k <= n; k++) { // dp for (int i = 1; i < k; i++) { for (int j = i + 1; j < k; j++) { // i,j,k序号由小到大 if (res - dis[i][j] > g[i][k] + g[k][j]) { // 减法防溢出 res = dis[i][j] + g[i][k] + g[k][j]; int x = i, y = j; cnt = 0; // 以前有过的路径也清空 while (x != y) { ans[cnt++] = y; y = path[i][y]; } ans[cnt++] = x; ans[cnt++] = k; // 序号最大的节点k } } } // floyd for (int i = 1; i <= n; i++) for (int j = 1; j <= n; j++) if (dis[i][j] > dis[i][k] + dis[k][j]) { dis[i][j] = dis[i][k] + dis[k][j]; path[i][j] = path[k][j]; // 这咋还和我理解的不一样呢? } } } int main() { while (cin >> n >> m) { // 邻接矩阵初始化 for (int i = 1; i <= n; i++) for (int j = 1; j <= n; j++) { dis[i][j] = g[i][j] = INF; path[i][j] = i; // 这里也是不一样,需要思考与整理 } // 读入边 while (m--) { int a, b, c; cin >> a >> b >> c; g[a][b] = g[b][a] = min(g[a][b], c); dis[a][b] = dis[b][a] = g[a][b]; } floyd(); if (res == INF) { puts("No solution."); continue; } for (int i = 0; i < cnt; i++) printf("%d%s", ans[i], (i == cnt - 1) ? "\n" : " "); } return 0; }