刚脑子卡了,在算总时间的时候有误,末尾最后一个节点为起始点,循环的最后一个节点就是真正意义上的最后一个点,这个点与起始点的距离加上去了
不是环:
先判断有没有路径:相邻点之间是否连接,若不连接路径之和就为NA
有路径但不是环:起点不等于终点
有路径但没有访问所有点
是环
若所有点只访问一次就是简单环,即n+1 ==cnt
#include <iostream>
#include <vector>
#include <algorithm>
#include <cstring>
using namespace std;
const int N = 210, INF = 0x3f3f3f3f;
int g[N][N]; //a点到b点的距离
int vers[320]; //存要求的点
bool vi[N];
int n, m;
int main()
{
memset(g, 0x3f, sizeof g);
cin >> n >> m;
for (int i = 0; i < m; i++)
{
int a, b, c;
cin >> a >> b >> c;
g[a][b] = g[b][a] = c;
}
int min = INF, min_id;
int k;
cin >> k;
for (int i = 1; i <= k; i++)
{
//初始化每点的状态
memset(vi, 0, sizeof vi);
int cnt;
cin >> cnt;
for (int j = 0; j < cnt; j++)
cin >> vers[j];
int sum = 0; // 路径长度
bool is_cycle = true;
//遍历所有点,看是否相邻点之间都有边
for (int j = 0; j < cnt-1; j++)
{
int a = vers[j], b = vers[j+1];
if (g[a][b] == INF)
{
is_cycle = false;
sum = -1;
break;
}
else sum += g[a][b];
vi[a] = true;
}
//判断每个点是否走过
for (int j = 1; j <= n; j++)
if (!vi[j])
{
is_cycle = false;
break;
}
//判断起点是否等于终点
if (vers[0] != vers[cnt-1]) is_cycle = false;
//判断是否为简单环
if (sum == -1) //没有路径,
printf("Path %d: NA (Not a TS cycle)\n", i);
else
{
if (!is_cycle) //有路径但不是环
printf("Path %d: %d (Not a TS cycle)\n", i, sum);
else
{
if (cnt == n+1)
printf("Path %d: %d (TS simple cycle)\n", i, sum);
else
printf("Path %d: %d (TS cycle)\n", i, sum);
if (min > sum) min = sum, min_id = i;
}
}
}
printf("Shortest Dist(%d) = %d\n", min_id, min);
return 0;
}
碎碎念:用了1H多写出来的,磕磕绊绊的,最后还有一个测试点段错误,数组没开够,一开始没有注意到不是环的条件之一是每个点都要访问
#include <iostream>
#include <vector>
#include <algorithm>
#include <cstring>
using namespace std;
const int N = 210, K = 1010, M = N*N;
int g[N][N]; //a点到b点的距离
int path[K][320];
bool vi[N];
int total[K];
vector<pair<int, int>> res;
int n, m, k;
//是否为环:相邻点之间有边,起点等于终点,每一个点都访问
bool is_cycle(int i, int cnt) //i第几条路径, cnt:这条路径有多少点
{
memset(vi, 0, sizeof i);
for (int j = 0; j < cnt-1; j++) //两点之间有边
{
if (g[path[i][j]][path[i][j+1]] == 0x3f3f3f3f)
{
total[i] = 0;
return false;
}
total[i] += g[path[i][j]][path[i][j+1]];
}
//每一个点都访问
for (int j = 0; j < cnt; j++)
vi[path[i][j]] = true;
for (int j = 1; j <= n; j++)
if (!vi[j])
return false;
//终点等于起点
if (path[i][0] != path[i][cnt-1])
return false;
return true;
}
//判断是否为简单环,每个点只访问一次,cnt==n+1
bool is_simple(int i, int cnt)
{
//若只有n+1个点
if (cnt == n+1)
return true;
return false;
}
int main()
{
memset(g, 0x3f, sizeof g);
cin >> n >> m;
while (m--)
{
int a, b, d;
cin >> a >> b >> d;
g[a][b] = g[b][a] = d;
}
//询问
cin >> k;
for (int i = 1; i <= k; i++)
{
int cnt;
cin >> cnt;
for (int j = 0; j < cnt; j++) cin >> path[i][j];
if (is_cycle(i, cnt))
{
if (is_simple(i, cnt))
printf("Path %d: %d (TS simple cycle)\n", i, total[i]);
else printf("Path %d: %d (TS cycle)\n", i, total[i]);
res.push_back({total[i], i});
}
else
{
if (total[i])
printf("Path %d: %d (Not a TS cycle)\n", i, total[i]);
else printf("Path %d: NA (Not a TS cycle)\n", i);
}
}
sort(res.begin(), res.end());
printf("Shortest Dist(%d) = %d\n", res[0].second, res[0].first);
return 0;
}