The “travelling salesman problem” asks the following question: “Given a list of cities and the distances between each pair of cities, what is the shortest possible route that visits each city and returns to the origin city?” It is an NP-hard problem in combinatorial optimization, important in operations research and theoretical computer science. (Quoted from “https://en.wikipedia.org/wiki/Travelling_salesman_problem”.)

In this problem, you are supposed to find, from a given list of cycles, the one that is the closest to the solution of a travelling salesman problem.

Input Specification:
Each input file contains one test case. For each case, the first line contains 2 positive integers N (2<N≤200), the number of cities, and M, the number of edges in an undirected graph. Then M lines follow, each describes an edge in the format City1 City2 Dist, where the cities are numbered from 1 to N and the distance Dist is positive and is no more than 100. The next line gives a positive integer K which is the number of paths, followed by K lines of paths, each in the format:

n C
​1
​​ C
​2
​​ … C
​n
​​

where n is the number of cities in the list, and C
​i
​​ 's are the cities on a path.

Output Specification:
For each path, print in a line Path X: TotalDist (Description) where X is the index (starting from 1) of that path, TotalDist its total distance (if this distance does not exist, output NA instead), and Description is one of the following:

TS simple cycle if it is a simple cycle that visits every city;
TS cycle if it is a cycle that visits every city, but not a simple cycle;
Not a TS cycle if it is NOT a cycle that visits every city.
Finally print in a line Shortest Dist(X) = TotalDist where X is the index of the cycle that is the closest to the solution of a travelling salesman problem, and TotalDist is its total distance. It is guaranteed that such a solution is unique.

Sample Input:
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
7
7 5 1 4 3 6 2 5
7 6 1 3 4 5 2 6
6 5 1 4 3 6 2
9 6 2 1 6 3 4 5 2 6
4 1 2 5 1
7 6 1 2 5 4 3 1
7 6 3 2 5 4 1 6
Sample Output:
Path 1: 11 (TS simple cycle)
Path 2: 13 (TS simple cycle)
Path 3: 10 (Not a TS cycle)
Path 4: 8 (TS cycle)
Path 5: 3 (Not a TS cycle)
Path 6: 13 (Not a TS cycle)
Path 7: NA (Not a TS cycle)
Shortest Dist(4) = 8

不难就是麻烦

//邻接矩阵存图,如果这条路径上的点都只出现一次,就是simple的,如果重复出现,就不是simple,如果前后不同或者中间断开另外讨论
#include<iostream>
#include<algorithm>
#include<vector>
#include<cstdio>
using namespace std;
const int maxn = 205;
int G[maxn][maxn];int main(){int n,m;int minDis = 1000000000,ans;cin>>n>>m;int u,v,dis;fill(G[0], G[0]+maxn*maxn,0);for(int i = 0; i < m; i++){cin>>u>>v>>dis;G[u][v] = G[v][u] = dis;}int k, num,x;cin>>k;for(int i = 1; i <= k; i++){cin>>num;int hashTable[maxn] = {0}, tempDis = 0;bool cycle = true;bool haveDis = true;bool simpleCycle = true;vector<int> path;for(int j = 0; j < num; j++){cin>>x;path.push_back(x);}if(path[0] != path[num-1]) cycle = false;for(int j = 0; j < num-1; j++){hashTable[path[j]]++;if(G[path[j]][path[j+1]] != 0) tempDis+=G[path[j]][path[j+1]];else haveDis = false;}for(int j = 1; j <= n; j++){if(j!=path[0] && hashTable[j] >=2) simpleCycle = false;}//还有一个判断circle就是是不是所有点都被访问if(num < n){cycle = false;simpleCycle = false;}for(int j = 1; j <= n; j++){if(hashTable[j] == 0) cycle = false;}if(tempDis < minDis && haveDis == true && cycle == true){minDis = tempDis;ans = i;}if(cycle == true && simpleCycle == true && haveDis==true) printf("Path %d: %d (TS simple cycle)\n",i,tempDis);else if(cycle == true && simpleCycle == false &&haveDis == true) printf("Path %d: %d (TS cycle)\n",i,tempDis);else if(cycle == false && haveDis == true) printf("Path %d: %d (Not a TS cycle)\n",i,tempDis);else printf("Path %d: NA (Not a TS cycle)\n",i);}printf("Shortest Dist(%d) = %d",ans,minDis);return 0;
}

二刷,写的差不多

//simple cycle:最后一个等于第一个,路径是通路,点集个数 -1等于n,去重后的个数=n
//ts cycle:最后一个等于第一个,路径通路,点集个数-1不等于n
//not:最后一个字符不等于第一个或者中间不连通
#include<iostream>
#include<vector>
#include<cstdio>
#include<algorithm>
#include<set>
using namespace std;
const int maxn = 205;
int G[maxn][maxn];
int main(){fill(G[0],G[0]+maxn*maxn,0);int n,m;cin>>n>>m;int u,v,dis;int minDis = 1000000000;int res;for(int i = 0; i < m; i++){cin>>u>>v>>dis;G[u][v] = G[v][u] = dis;}int q,k,dian;cin>>q;for(int i = 1; i <= q; i++){cin>>k;vector<int> v;set<int> s;int distance = 0;bool connect = true;bool simple = true;bool cycle = true;for(int j = 0; j < k; j++){cin>>dian;v.push_back(dian);s.insert(dian);}for(int j = 0; j < k - 1; j++){if(G[v[j]][v[j+1]] != 0){distance += G[v[j]][v[j+1]];}else{connect = false;break;}}if(k - 1 != n) simple = false;if(v[k-1] != v[0] || s.size() != n) cycle = false;if(simple == true && connect == true && cycle == true) printf("Path %d: %d (TS simple cycle)\n",i,distance);else if(simple == false && connect == true && cycle == true) printf("Path %d: %d (TS cycle)\n",i,distance);else if(cycle == false && connect == true) printf("Path %d: %d (Not a TS cycle)\n",i,distance);else if(connect == false) printf("Path %d: NA (Not a TS cycle)\n",i);if(connect == true && cycle == true){if(distance < minDis){minDis = distance;res = i;}}}printf("Shortest Dist(%d) = %d",res,minDis);return 0;
}

没有全访问也不是圆,不是判断j和j+1有没有连通,而是v[j]和v[j+1]

//simple cycle:访问了每一个点,并且最后一个点和原点相等,用set来判断是否访问了每一个点
//ts cycle:访问了每一个点,最后一个点和原点相等,但是k-1和n不相等
//not cycle:最后一个点和原点不相等或者没有访问每一个点;两种情况,一种是通的,求出距离,一种是断的,na
#include<iostream>
#include<vector>
#include<unordered_set>
#include<cstdio>
using namespace std;
const int maxn = 205;
int G[maxn][maxn];int main(){int n,m;cin>>n>>m;int u,v,dis;for(int i = 0; i < m; i++){cin>>u>>v>>dis;G[u][v] = G[v][u] = dis;}int q,k;cin>>q;int minDis = 1e9;int ans;for(int i = 1; i <= q; i++){cin>>k;vector<int> v(k+1);unordered_set<int> s;int totalDis = 0;bool isCycle = true;//有两种情况会让它不是圆bool connected = true;bool isSimple = true;for(int j = 0; j < k; j++){cin>>v[j];s.insert(v[j]);}if(v[0] != v[k-1]) isCycle = false;for(int j = 0; j < k-1; j++){if(G[v[j]][v[j+1]] == 0){connected = false;isCycle = false;break;}totalDis += G[v[j]][v[j+1]];}if(k-1 != n) isSimple = false;if(s.size() != n) isCycle = false;if(connected == false) printf("Path %d: NA (Not a TS cycle)\n",i);else if(isCycle == false && connected == true) printf("Path %d: %d (Not a TS cycle)\n",i,totalDis);else if(isSimple == false && isCycle == true) printf("Path %d: %d (TS cycle)\n",i,totalDis);else if(isSimple == true && isCycle == true) printf("Path %d: %d (TS simple cycle)\n",i,totalDis);if(isCycle == true && totalDis < minDis){minDis = totalDis;ans = i;}}printf("Shortest Dist(%d) = %d\n",ans,minDis);return 0;
}

1150 Travelling Salesman Problem (25分)相关推荐

  1. 1150 Travelling Salesman Problem (25 分)【难度: 难 / 知识点: 图 模拟 未完成】

    https://pintia.cn/problem-sets/994805342720868352/problems/1038430013544464384

  2. PAT甲级1150 Travelling Salesman Problem:[C++题解]旅行商问题、图论

    文章目录 题目分析 题目链接 题目分析 来源:acwing 分析: 旅行商问题:访问每个城市并回到原城市的最短路. 思路: 1)判断相邻两点有无距离(NA):2)每个点是否都能到:3)是否是回路:4) ...

  3. PAT 1150 Travelling Salesman Problem(25 分)- 甲级

    The "travelling salesman problem" asks the following question: "Given a list of citie ...

  4. cf1504. Travelling Salesman Problem

    cf1504. Travelling Salesman Problem 题意: n个城市,编号1~n,每个城市有美丽值a[i],现在要从城市1出发,其他所有城市走一遍,最后回到城市1,城市i到j的花费 ...

  5. 单目标应用:求解单仓库多旅行商问题(Single-Depot Multiple Travelling Salesman Problem, SD-MTSP)的人工兔优化算法ARO

    一.算法简介 人工兔优化算法(Artificial Rabbits Optimization ,ARO)由Liying Wang等人于2022年提出,该算法模拟了兔子的生存策略,包括绕道觅食和随机躲藏 ...

  6. 旅行商问题(travelling salesman problem, TSP) 解题报告

    旅行商问题是个熟知的问题.这次是因为coursera上面选的算法课而写代码实现.这里做个简单总结. 测试程序: 25 20833.3333 17100.0000 20900.0000 17066.66 ...

  7. 【HDU 5402】Travelling Salesman Problem(构造)

    被某题卡SB了,结果这题也没读好...以为每一个格子能够有负数就当搜索做了.怎么想也搜只是去,后来发现每一个格子是非负数,那么肯定就是构造题. 题解例如以下: 首先假设nn为奇数或者mm为奇数,那么显 ...

  8. Codeforces Round #712 (Div. 2) E. Travelling Salesman Problem 思维转换

    传送门 文章目录 题意: 思路: 题意: 给你nnn个点,从iii到jjj的花费是max(ci,aj−ai)max(c_i,a_j-a_i)max(ci​,aj​−ai​),求从111开始经过每个点再 ...

  9. 旅行商问题(Travelling salesman problem, TSP)

    旅行商问题建模与证明 – 个人学习记录

  10. C++学习之路 | PTA(天梯赛)—— L2-010 排座位 (25分)(带注释)(并查集)(精简)

    L2-010 排座位 (25分) 布置宴席最微妙的事情,就是给前来参宴的各位宾客安排座位.无论如何,总不能把两个死对头排到同一张宴会桌旁!这个艰巨任务现在就交给你,对任何一对客人,请编写程序告诉主人他 ...

最新文章

  1. Roundgod and Milk Tea 贪心
  2. python求正方体体积_「高中数学」简单几何体的面积与体积相关知识点整理+例题...
  3. python拼接两个数组_在Python中连接两个数组
  4. 电商促销惊喜海报设计模板,会讲故事的素材
  5. 输入 3 个正数,判断能否构成一个三角形
  6. 7-8 12-24小时制 (15 分)
  7. 折腾小米盒子1s记录
  8. 国外 Warez 网站 杂集
  9. java dateutil 获取时间戳_java获取时间戳的方法
  10. 最小二乘支持向量机(基于MATLAB)
  11. android支付宝运动修改器,一键修改支付宝运动步数-修改支付宝运动步数工具下载不要root手机版-西西软件下载...
  12. 数据安全生命周期管理介绍(一)
  13. JavaScript制作动画
  14. RGB 和 CYMK 的区别
  15. Cookie是什么及用法详解
  16. 网站UI设计的注意事项
  17. 未来乡村|数字乡村|数字化解决方案|乡村数字化体验
  18. NeuralProphet之二:季节性(Seasonality)
  19. JAVA实战项目【2】(面向对象图书小练习)
  20. 展望2007,十类经典装机软件(全心收集了39款!)

热门文章

  1. 【独家首发评测】Oh!Monster贺岁上市:我们都爱打小怪兽
  2. 数据结构 | 多维列表(数组)转换为一维列表
  3. 推荐21个GitHub上好用又有趣的移动端项目(涵盖初中高阶)
  4. 【院校推荐】2023武汉大学电气考研就业分析
  5. 阿里及自建机房费用简记
  6. Inline sharding algorithms expression `xxx` and sharding column `xx` not mat
  7. Intent跳转指定APP和跳转浏览器
  8. 001_各种网页错误代码解释(400.404.504等)
  9. Python爬取章鱼猫Octocat全部图片
  10. Parallax-tolerant Image Stitching - 解决大视差图片拼接的方法