这道题虽然是以TSP问题作为背景,但是不需要任何TSP算法的知识,只要按照题目模拟即可。在做题的时候,最重要的就是要细心,这道题情况有很多种,要把所有的情况都依次划分出来。
我一开始WA了一个点,检查之后,发现是当我判断是否所有的点均被访问的时候,并没有判断1到n的所有点,而是判断了存储路径数组里的点是否被访问过,这样一来,就根本不会有没有访问过的点了。修复了这个问题之后,终于AC了,开心!
代码最下方的注释里面写了那个检查出我的错误的数据。
#include <iostream>
#include<vector>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<map>
#include<cstdlib>
#include<queue>
#include<cstring>
#include<set>
#include<list>
#include<unordered_set>
using namespace std;
int n,m;
int dis[210][210];
int vis[210];
int main()
{
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
{
if(i!=j)dis[i][j]=-1;
else dis[i][j]=0;
}
for(int i=1;i<=m;i++)
{
int x,y,z;
scanf("%d%d%d",&x,&y,&z);
dis[x][y]=dis[y][x]=z;
}
int k;
scanf("%d",&k);
int ans=0x3f3f3f3f,ansid;
for(int i=1;i<=k;i++)
{
printf("Path %d: ",i);
int total;
scanf("%d",&total);
vector<int>v;
for(int j=1;j<=total;j++)
{
int next;
scanf("%d",&next);
v.push_back(next);
}
int length=0;
bool isExist=true;
for(int i=0;i<v.size()-1;i++)
{
int cur=v[i];
int next=v[i+1];
if(dis[cur][next]!=-1)
{
length+=dis[cur][next];
}
else{
isExist=false;
break;
}
}
if(isExist)
printf("%d ",length);
else
{
printf("NA (Not a TS cycle)\n");
continue;
}
bool TSP=true;
if(v.size()<n+1)
{
printf("(Not a TS cycle)\n");
TSP=false;
}
else{
bool visAll=true,isHeadEqualTail=true;
fill(vis+1,vis+n+1,0);
for(int j=0;j<v.size();j++)
{
vis[v[j]]++;
}
for(int j=1;j<=n;j++)
{
if(vis[j]==0)
{
visAll=false;
break;
}
}
if(v.front()!=v.back())
isHeadEqualTail=false;
if(!isHeadEqualTail)
{
printf("(Not a TS cycle)\n");
TSP=false;
}
else if(!visAll)
{
printf("(Not a TS cycle)\n");
TSP=false;
}
else
{
bool isSimple=true;
for(int j=1;j<v.size()-1;j++)
{
if(vis[v[j]]>1)
{
isSimple=false;
break;
}
}
if(isSimple)
printf("(TS simple cycle)\n");
else
printf("(TS cycle)\n");
}
}
if(isExist&&TSP)
{
if(length<ans)
{
ans=length;
ansid=i;
}
}
}
printf("Shortest Dist(%d) = %d",ansid,ans);
}
/*
6 10
6 2 1
3 4 1
1 5 1
2 5 1
3 1 8
4 1 6
1 6 1
6 3 1
1 2 1
4 5 1
20
8 1 1 1 1 6 6 6 1
*/