• PAT甲级1150Travelling Salesman Problem


    题目链接

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

    题解

    题目要求

    • 现在给你一些环,请你找到其中与旅行商问题答案最接近的那个环(旅行商问题的定义在此不再说明)
    • 输入
      • N:大于2,不超过200,城市的数量
      • M:无向图中边的数量,
      • M条边:每条边表示为City1 City2 Dist,其中城市索引为[1,N],城市间距离为不超过100的正数
      • K:正整数,path的数量
      • K条path:每条path的格式为:n c1 c2 c3 … cn,其中n是path中城市的数量,ci是城市索引
    • 输出
      • 对于每条path,输出Path X: TotalDist (Description),其中X是[1,K],TotalDist是总距离(不存在则输出NA),Description是
        • 经过每个城市的简单环:TS simple cycle
        • 经过每个城市的环,但不是简单环:TS cycle
        • 不是经过每个城市的环:Not a TS cycle
      • 最终输出Shortest Dist(X) = TotalDist,其中X是和旅行商问题解最接近的那个环的索引,TotalDist是其距离总和。(已确保只有一个解)

    解题思路

    • 距离用二维数组表示,默认值为0,为0则说明两个城市间不存在边

    • 读取每条path时,用一维数组存储某个节点被访问的次数(注意城市索引是1到N)

      在路径合法的前提下

      • TS cycle:即经过每个城市并且是一个环,即每个城市被访问的次数都大于0且首尾城市相同
      • TS simple cycle:在TS cycle的基础上,要求没有子环,只有起点城市被访问过2次,其它城市都只被访问过一次
    • 将k个path的结果存放在一维数组中

    代码

    // Problem: PAT Advanced 1150
    // URL: https://pintia.cn/problem-sets/994805342720868352/problems/1038430013544464384
    // Tags: Graph TSP
    
    #include <iostream>
    #include <vector>
    #include <climits>
    using namespace std;
    
    int distances[205][205]; // 各个城市之间的距离。如果为0,则说明两个城市间无边、不可直达
    
    int main()
    {
        int n, m, k;
        scanf("%d %d", &n, &m);
    
        int c1, c2, dist;
        for (int i = 0; i < m; i++){ // 存储各个城市之间的距离
            scanf("%d %d %d", &c1, &c2, &dist);
            distances[c1][c2] = distances[c2][c1] = dist;
        }
    
        int bestX, bestDist = INT_MAX;
        scanf("%d", &k);
        for(int x = 1; x <= k; x++){
            vector<int> visited(n + 1, 0);
            int numOfCities, firstCity, pathTotalDist = 0;
            bool pathIslegal = true;
            scanf("%d %d", &numOfCities, &firstCity);
            visited[firstCity] += 1; // 访问第一个城市
            c1 = firstCity; // 更新上一个城市
    
            for(int i = 0 ; i < numOfCities - 1; i++){
                scanf("%d", &c2); // 读取当前城市
                if (distances[c1][c2] != 0){
                    visited[c2] += 1;
                    pathTotalDist += distances[c1][c2]; // 计算该路径的总距离
                }
                else{ // path中两个城市不存在边
                    pathIslegal = false;
                }
                c1 = c2; // 更新上一个城市
            }
    
            if (!pathIslegal){ // 路径非法
                printf("Path %d: NA (Not a TS cycle)
    ", x);
                continue;
            }
    
            if (firstCity != c2){ // 在路径合法的前提下,第一个城市和最后一个城市不同,则该路径不是环
                printf("Path %d: %d (Not a TS cycle)
    ", x, pathTotalDist);
                continue;
            }
    
            bool isTS = true;
            for (int i = 1; i < n + 1; i++){
                if (visited[i] < 1){
                    isTS = false;
                    break;
                }
            }
            if (!isTS){ // 该路径没有经过所有城市
                printf("Path %d: %d (Not a TS cycle)
    ", x, pathTotalDist);
                continue;
            }
    
            bool isSimple = true;
            for (int i = 1; i < n + 1; i++){ // 已确保是环且经过所有城市,判断是否是简单环,并更新最短TS环路
                if (pathTotalDist < bestDist){
                    bestX = x;
                    bestDist = pathTotalDist;
                }
    
                if (i != firstCity && visited[i] > 1){
                    isSimple = false;
                }
            }
    
            if (isSimple)
                printf("Path %d: %d (TS simple cycle)
    ", x, pathTotalDist);
            else
                printf("Path %d: %d (TS cycle)
    ", x, pathTotalDist);
        }
    
        printf("Shortest Dist(%d) = %d
    ", bestX, bestDist);
        return 0;
    }
    

    作者:@臭咸鱼

    转载请注明出处:https://www.cnblogs.com/chouxianyu/

    欢迎讨论和交流!


  • 相关阅读:
    css 移动端像素,rem适配详解
    css,图片和文字在父元素垂直居中,且图片和文字在中线对齐排列的几种方式
    css弹性盒子桃园三兄弟之:flexgrow、flexshrink、flexbasis详解
    less的基本使用
    css 利用flex居中对齐
    css 高度塌陷和外边距折叠问题详解,(BFC)
    HTML行内元素、块状元素、行内块状元素的区别
    css flex弹性布局学习总结
    shell学习笔记
    Ant入门教程
  • 原文地址:https://www.cnblogs.com/chouxianyu/p/13617879.html
Copyright © 2020-2023  润新知