PAT甲级1150 Travelling Salesman Problem (25分)|C++实现

一、题目描述

原题链接
在这里插入图片描述

Input Specification:

在这里插入图片描述

​​Output Specification:

在这里插入图片描述

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

二、解题思路

如果一个序列经过所有结点并且最后一个结点是第一个结点,则构成一个TS cycle,除了第一个结点和最后一个结点,如果经过某个结点两次,那么就不是一个simple cycle,前后结点不相连则应该输出NA。基于这些,代码就不难设计出来了,详情可见代码注释。

三、AC代码

#include<iostream>
#include<cstdio>
#include<vector>
#include<algorithm>
using namespace std;
const int maxn = 220;
const int INF = 100000;
int G[maxn][maxn];  //邻接矩阵
int main()
{
    
    
    int N, M, Q, K, tmp, a, b, ansdis = INF, anspath;
    scanf("%d%d", &N, &M); 
    fill(G[0], G[0]+maxn*maxn, INF);    //初始化为INF
    for(int i=0; i<M; i++)  //输入数据
    {
    
    
        scanf("%d%d%d", &a, &b, &tmp);
        G[a][b] = G[b][a] = tmp;
    }
    scanf("%d", &Q);
    for(int i=0; i<Q; i++)
    {
    
    
        int tempdis = 0;
        int cnt[N+1] = {
    
    0};
        bool na = false, ts = true, sim = true; //标志是否应该输出NA,是否为TS cycle,是否simple
        vector<int> vertex;
        scanf("%d", &K);
        vertex.resize(K);
        for(int j=0; j<K; j++)
        {
    
    
            scanf("%d", &vertex[j]);
            if(j > 0)
            {
    
    
                if(G[vertex[j-1]][vertex[j]] < INF) tempdis += G[vertex[j-1]][vertex[j]];   //如果前后结点是连接的
                else
                {
    
    
                    na = true;  //前后结点不连接则应输出NA
                    ts = false;
                }
            }
            cnt[vertex[j]]++;   //统计每个结点出现的次数
            if(j < K-1 && cnt[vertex[j]] > 1)  sim = false; //除了最后一个结点和第一个节点是一样的,如果有结点出现了两次则不是simple cycle
        }
        for(int j=1; j<=N; j++)
            if(cnt[j] == 0) ts = false; //如果存在没有遍历到的点
        if(vertex[0] == vertex[K-1] && ts && tempdis < ansdis)  //更新答案
        {
    
    
            ansdis = tempdis;
            anspath = i+1;
        }
        if(na)  //输出
            printf("Path %d: NA (Not a TS cycle)\n", i+1);
        else if(vertex[0] != vertex[K-1] || !ts)
            printf("Path %d: %d (Not a TS cycle)\n", i+1, tempdis);
        else
            printf("Path %d: %d %s\n", i+1, tempdis, sim ? "(TS simple cycle)" : "(TS cycle)");
    }
    printf("Shortest Dist(%d) = %d", anspath, ansdis);
    return 0;
}

猜你喜欢

转载自blog.csdn.net/weixin_42393947/article/details/109107520