给定一张图,求图中一个至少包含三个点的环,环上的点不重复,并且环上的边的长度之和最小.
点数不超过100个
输出方案
无向图:
1 /*Huyyt*/ 2 #include3 #define mem(a,b) memset(a,b,sizeof(a)) 4 #define pb push_back 5 using namespace std; 6 typedef long long ll; 7 typedef unsigned long long ull; 8 const int mod = 1e9 + 7; 9 const int gakki = 5 + 2 + 1 + 19880611 + 1e9; 10 const int MAXN = 3e2 + 5, MAXM = 2e5 + 5; 11 int a[MAXN][MAXN], d[MAXN][MAXN], pos[MAXN][MAXN]; 12 int n, m; 13 int ans = 0x3f3f3f3f; 14 vector<int> path; 15 void get_path(int x, int y) 16 { 17 if (pos[x][y] == 0) 18 { 19 return ; 20 } 21 get_path(x, pos[x][y]); 22 path.push_back(pos[x][y]); 23 get_path(pos[x][y], y); 24 } 25 int main() 26 { 27 scanf("%d %d", &n, &m); 28 mem(a, 0x3f); 29 for (int i = 1; i <= n; i++) 30 { 31 a[i][i] = 0; 32 } 33 for (int i = 1; i <= m; i++) 34 { 35 int x, y, z; 36 scanf("%d %d %d", &x, &y, &z); 37 a[x][y] = a[y][x] = min(a[x][y], z); 38 } 39 memcpy(d, a, sizeof(a)); 40 for (int k = 1; k <= n; k++) 41 { 42 //刚开始循环时 d[i][j]表示经过编号不超过k-1的节点从i到j的最短路 43 for (int i = 1; i < k; i++) 44 { 45 for (int j = i + 1; j < k; j++) 46 { 47 if ((ll)d[i][j] + a[j][k] + a[k][i] < ans) 48 { 49 ans = d[i][j] + a[j][k] + a[k][i]; 50 path.clear(); 51 path.push_back(i); 52 get_path(i, j); 53 path.push_back(j), path.push_back(k); 54 } 55 } 56 } 57 for (int i = 1; i <= n; i++) 58 { 59 for (int j = 1; j <= n; j++) 60 { 61 if (d[i][j] > d[i][k] + d[k][j]) 62 { 63 d[i][j] = d[i][k] + d[k][j]; 64 pos[i][j] = k; 65 } 66 } 67 } 68 } 69 if (ans == 0x3f3f3f3f) 70 { 71 printf("No solution.\n"); 72 } 73 else 74 { 75 for (int i = 0; i < path.size(); i++) 76 { 77 printf("%d ", path[i]); 78 } 79 printf("\n"); 80 } 81 return 0; 82 }
有向图:
有向图直接floyd求出最小的自身到自身的距离 即为答案(注意初始化全为INF)