PAT A1150 Travelling Salesman Problem
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
-
关键:
returns to the origin city
-
思路 1:
理解题意按情况分类:
- 不是一条路径(flag == true):
NA (Not a TS cycle)
- 是一条路(flag == false, 走得通,不知道有没有走回头路的,我这里按没有,增设了一个vis[]数组)分为:只有是路就输出距离dis
- 2-1:是环路( a. 点数=边数 b. 头尾同节点)-Ps:Min只在环中求(不考虑没遍历所有城市的路径)
- 2-1-1:是简单环,节点不重复(节点数==总城市数)(TS simple cycle)
- 2-1-2:不是简单环(TS cycle)
- 2-2:不是环路:(Not a TS cycle)
- code 1:
#include <bits/stdc++.h>
using namespace std;
const int maxn = 300;
const int INF = 0x3fffffff;
int n, m;
int G[maxn][maxn], path[maxn];
bool vis[maxn];
int main(){
int c1, c2, k, nC, tmpC;
scanf("%d %d", &n, &m);
fill(G[0], G[0]+maxn*maxn, INF);
for(int i = 0; i < m; ++i){
scanf("%d %d", &c1, &c2);
scanf("%d", &G[c1][c2]);
G[c2][c1] = G[c1][c2];
}
scanf("%d", &k);
int Min = INF, ans = -1;
for(int i = 1; i <= k; ++i){
scanf("%d", &nC);
unordered_set<int> ve;
for(int j = 0; j < nC; ++j){
scanf("%d", &path[j]);
ve.insert(path[j]);
}
int dis = 0;
bool flag = false;
fill(vis, vis+maxn, false);
for(int j = 1; j < nC; ++j){
vis[j-1] = true;
if(vis[j] == false && G[path[j-1]][path[j]] != INF){
dis += G[path[j-1]][path[j]];
}else flag = true;
}
printf("Path %d: ", i);
if(flag){ //1. 不一条路径
printf("NA (Not a TS cycle)\n");
}else{ //2.是一条路径
printf("%d ", dis);
if(ve.size() == n && path[0] == path[nC-1]){ //2-1是cycle
if(ve.size() == nC-1){ //2-1-1:simple
printf("(TS simple cycle)\n");
}else printf("(TS cycle)\n"); //2-1-2 nonsimple
if(dis < Min){
Min = dis;
ans = i;
}
}else printf("(Not a TS cycle)\n"); //2-2不是cycle
}
}
printf("Shortest Dist(%d) = %d\n", ans, Min);
return 0;
}
- T2 code:
#include <bits/stdc++.h>
using namespace std;
const int maxn = 510, INF = 0x3fffffff;
int G[maxn][maxn];
int main(){
int nv, ne;
scanf("%d %d", &nv, &ne);
for(int i = 0; i < ne; ++i){
int c1, c2, td;
scanf("%d %d %d", &c1, &c2, &td);
G[c1][c2] = G[c2][c1] = td;
}
int nq, min_path, min_dis = INF;
scanf("%d", &nq);
for(int i = 1; i <= nq; ++i){
int qnv, first, pre, now, sum_dis = 0;
scanf("%d", &qnv);
bool connect = true;
unordered_set<int> st;
for(int j = 0; j < qnv; ++j){
scanf("%d", &now);
if(j == 0) first = now;
else if(G[pre][now] != 0) sum_dis += G[pre][now];
else connect = false;
st.insert(now);
pre = now;
}
printf("Path %d: ", i);
if(connect){
printf("%d ", sum_dis);
if(first == now && st.size() == nv){
if(qnv == nv + 1){
printf("(TS simple cycle)\n");
}else{
printf("(TS cycle)\n");
}
if(sum_dis < min_dis){
min_dis = sum_dis;
min_path = i;
}
}else{
printf("(Not a TS cycle)\n");
}
}else{
printf("NA (Not a TS cycle)\n");
}
}
printf("Shortest Dist(%d) = %d", min_path, min_dis);
return 0;
}
- T3 code:
#include <bits/stdc++.h>
using namespace std;
const int maxn = 220;
int G[maxn][maxn];
int main()
{
int n, m;
scanf("%d %d", &n, &m);
for(int i = 0; i < m; ++i)
{
int c1, c2, dis;
scanf("%d %d %d", &c1, &c2, &dis);
G[c1][c2] = G[c2][c1] = dis;
}
int q, min_dis = INT_MAX, min_path = 0;
scanf("%d", &q);
for(int i = 1; i <= q; ++i)
{
int nq, first, last, pre, sum_dis = 0;
bool flg = true;
scanf("%d", &nq);
unordered_set<int> st;
for(int j = 0; j < nq; ++j)
{
scanf("%d", &last);
if(j == 0) first = last;
else
{
if(G[pre][last] == 0) flg = false;
else sum_dis += G[pre][last];
}
pre = last;
st.insert(last);
}
printf("Path %d: ", i);
if(flg)
{
printf("%d ", sum_dis);
}else printf("NA ");
if(st.size() == n && last == first && flg)
{
if(sum_dis < min_dis)
{
min_dis = sum_dis;
min_path = i;
}
printf("%s\n", nq == n + 1 ? "(TS simple cycle)" : "(TS cycle)");
}else printf("(Not a TS cycle)\n");
}
printf("Shortest Dist(%d) = %d", min_path, min_dis);
return 0;
}