1150 Travelling Salesman Problem
题目大意
给出一条路径,判断这条路径是不是这个图的旅行商环路、简单旅行商环路和非旅行商环路。
基本思路
如果给出的路径存在某两个连续的点不可达第一个结点和最后一个结点不同或者这个路径没有访问过图中所有的点,那么它就不是一个旅行商环路。如果满足了旅行商环路的条件,那么再判断这个旅行商环路是否是简单旅行商环路,即是否访问过n+1个结点并且源点访问两次。最后输出这些旅行商环路中经过的路径最短的路径编号和路径长度。
代码
具体数据结构和相似思路请看代码
#include <iostream>
#include <algorithm>
#include <vector>
#include <set>
using namespace std;
const int MAXN=210;
const int INF=100000000;
int n,m,k;
int G[MAXN][MAXN];
int main(){
cin>>n>>m;
fill(G[0], G[0] + MAXN * MAXN, INF);
for(int i=0;i<m;i++){
int v1,v2,dis;
cin>>v1>>v2>>dis;
G[v1][v2]=G[v2][v1]=dis;
}
int mindis=INF,pathindex=-1;
int cnt = 1;
cin>>k;
for(int i=0;i<k;i++){
int num;
cin>>num;
vector<int> v;
set<int> s;
for (int j = 0; j < num;j++){
int ans;
cin>>ans;
v.push_back(ans);
s.insert(ans);
}
int flag = 1;
if(s.size()<n||v[0]!=v[num-1]){
flag = 0;
}
int dis=0;
for (int i = 0; i < num-1 ;i++){
int id1 = v[i], id2 = v[i + 1];
dis += G[id1][id2];
if(G[id1][id2]==INF){
flag = 0;
dis=-1;
break;
}
}
if(!flag){
if(dis==-1){
cout << "Path " << cnt++ << ": "<<"NA"
<< " (Not a TS cycle)" << endl;
continue;
}else{
cout << "Path " << cnt++ << ": "<<dis
<< " (Not a TS cycle)" << endl;
continue;
}
}
if(v[0]==v[num-1]&&v.size()==n+1){
cout << "Path " << cnt++ << ": "<<dis
<< " (TS simple cycle)" << endl;
}else{
cout << "Path " << cnt++ << ": "<<dis
<< " (TS cycle)" << endl;
}
if(dis<mindis){
mindis = dis;
pathindex = cnt - 1;
}
}
printf("Shortest Dist(%d) = %d", pathindex, mindis);
}
|