PAT_甲级_1150 Travelling Salesman Problem (25point(s)) (C++)【旅行推销商问题(简化版)/逻辑分析】

目录

1,题目描述

题目大意

2,思路

数据结构

算法

3,AC代码

4,解题过程


1,题目描述

 

 

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

题目大意

1,给出一个图,以及多个查询序列,判断序列满足的类型 :

  1. Not a TS cycle:存在相邻两点无通路 || 起点终点不同 || 没有经过所有的城市;
  2. TS cycle:满足条件1,但经过城市不止一次;
  3. TS simple cycle:满足条件1,且只经过每个城市一次;

2,路径长度

  • 对于满足任意两点联通的路径,输出其路径长度;
  • 否则输出NA;

3,最短路径为哪一条,以及路径值

 

2,思路

数据结构

  • int graph[205][205]:邻接矩阵构建图(0表示两点间无通路);
  • unordered_set<int> record:记录去过的城市,用record.size()判断是否去过每个城市;

算法

  1. 邻接矩阵记录图                                                                                                  
  2. 接受每个路径信息时、判断相邻两点是否联通、更新tempDis、记录去过的城市:
  3. 若任意两点均联通,根据record.size()判断是否为cycle或simple cycle,并更新minDis以及PathID:
  4. 输出最短的一条路径信息:

 

3,AC代码

#include<bits/stdc++.h>
using namespace std;
int N, M, K, graph[205][205], minDis = INT_MAX, pathID;

int main(){
#ifdef ONLINE_JUDGE
#else
    freopen("1.txt", "r", stdin);
#endif // ONLINE_JUDGE
    scanf("%d%d", &N, &M);
    int c1, c2, d;
    while(M--){
        scanf("%d%d%d", &c1, &c2, &d);
        graph[c1][c2] = graph[c2][c1] = d;
    }
    scanf("%d", &K);
    for(int i = 1; i <= K; i++){
        int num, temDis = 0, data[205], flag = -1;
        unordered_set<int> record;
        scanf("%d%d", &num, &data[0]);
        record.insert(data[0]);
        for(int j = 1; j < num; j++){
            scanf("%d", &data[j]);
            if(flag == -1){
                if(graph[data[j-1]][data[j]] == 0){             //含有不通的路 此时flag=0
                    flag = 0;
                    printf("Path %d: NA (Not a TS cycle)\n", i);
                }else{
                    temDis += graph[data[j-1]][data[j]];
                }
                record.insert(data[j]);                         //判断是否每个城市都去过
            }
        }
        if(flag == -1){                                         //每段都是通路
            if(data[0] != data[num-1] || record.size() != N)    //起点终点不同 || 没有去过所有城市
                printf("Path %d: %d (Not a TS cycle)\n", i, temDis);
            else{                                               //起点终点相同 && 去过所有城市
                if(num != N + 1) printf("Path %d: %d (TS cycle)\n", i, temDis);//城市去过不止一次
                else printf("Path %d: %d (TS simple cycle)\n", i, temDis);

                if(minDis > temDis){                            //更新最短路径信息
                    minDis = temDis;
                    pathID = i;
                }
            }
        }
    }
    printf("Shortest Dist(%d) = %d", pathID, minDis);
    return 0;
}

4,解题过程

一发入魂o(* ̄▽ ̄*)ブ

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值