success判断是否是一个访问了每个城市的回路
注意要判断好几个条件:
- 是否路径可达,即从给定路线的相邻两点是否相连
- 判断是否每个城市都访问到了
- 判断是否是回路
判断是否是简单回路(即除了起点终点,每个点只访问一次)就很简单了,在success为true的前提下(即是是一个访问了每个城市的回路),判断给定路径的点的数量是否等于n + 1即可
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
const int N = 210, INF = 0x3f3f3f3f;
int n, m;
int g[N][N];
int ver[310];
bool st[N];
int main() {
memset(g, 0x3f, sizeof(g));
cin >> n >> m;
for (int i = 0; i < m; i++) {
int x, y, z;
cin >> x >> y >> z;
g[x][y] = g[y][x] = z;
}
int k;
cin >> k;
int min_id, min_dist = INF;
for (int T = 1; T <= k; T++) {
memset(st, 0, sizeof st);
int cnt;
cin >> cnt;
for (int i = 0; i < cnt; i++) {
cin >> ver[i];
st[ver[i]] = true;
}
/*
success判断是否是一个访问了每个城市的回路
注意要判断好几个条件:
1. 是否路径可达,即从给定路线的相邻两点是否相连
2. 判断是否每个城市都访问到了
3. 判断是否是回路
*/
bool success = true;
int sum = 0;
for (int i = 0; i < cnt - 1; i++) {
if (g[ver[i]][ver[i + 1]] == INF) {
success = false;
sum = -1;// sum置成-1,代表距离不存在,即存在路线的相邻两点不相连,输出 NA
break;
} else {
sum += g[ver[i]][ver[i + 1]];
}
}
// 判断是否每个城市都访问到了
for (int i = 1; i <= n; i++) {
if (!st[i]) {
success = false;
break;
}
}
// 判断是否是回路
if (ver[0] != ver[cnt - 1]) success = false;
if (sum == -1) {
printf("Path %d: NA (Not a TS cycle)\n", T);
}
else {
if (!success) {
printf("Path %d: %d (Not a TS cycle)\n", T, sum);
}
else {
if (sum < min_dist) {
min_dist = sum;
min_id = T;
}
if (cnt == n + 1) {// 判断是否是简单回路
printf("Path %d: %d (TS simple cycle)\n", T, sum);
}
else {
printf("Path %d: %d (TS cycle)\n", T, sum);
}
}
}
}
printf("Shortest Dist(%d) = %d", min_id, min_dist);
return 0;
}