被计组实验真冲昏了头脑。。水一发先。
最小环+记录路径;
几个sb点。题目没看,以为是单向边。每次记录路径递归写重(开头结尾多记录一遍)。重边忘处理。
#include <cstdio> #include <cstring> #define INF 10000000 using namespace std; int n, m, x, y, mini, minj, g[105][105], k; int w[105][105], f[105][105], ans[105], min; int now; void find(int x, int y) { if(g[x][y] == 0) return; find(x, g[x][y]); ans[now ++] = g[x][y]; find(g[x][y], y); } int main() { scanf("%d%d", &n, &m); min = INF; for(int i = 1; i <= n; i ++) for(int j = 1; j <= n; j ++) { w[i][j] = INF; f[i][j] = INF; } for(int i = 0; i < m; i ++) { scanf("%d%d", &x, &y); scanf("%d", &k); if(f[x][y] > k) f[x][y] = f[y][x] = w[y][x] = w[x][y] = k; } for(int k = 1; k <= n; k ++) { mini = 0, minj = 0; for(int i = 1; i < k; i ++) for(int j = 1; j < k; j ++) if(i != j) if(min > w[k][i]+f[i][j]+w[j][k]) { min = w[k][i]+f[i][j]+w[j][k]; mini = i, minj = j; } // printf("%d %d %d %d\n", k, min, mini, minj); if(mini != 0) { ans[0] = minj; ans[1] = k; ans[2] = mini; now = 3; find(mini, minj); } for(int i = 1; i <= n; i ++) for(int j = 1; j <= n; j ++) if(f[i][j] > f[i][k]+f[k][j]) { f[i][j] = f[i][k]+f[k][j]; g[i][j] = k; } } // printf("%d\n", min); if(min < INF) for(int i = 0; i < now; i ++) if(i != now-1) printf("%d ", ans[i]); else printf("%d\n", ans[i]); else printf("No solution.\n"); return 0; }
时间: 2024-09-29 23:10:56