PAT_甲級_1150 Travelling Salesman Problem

題目大意:

給定一個N個頂點和M條邊的無向圖,K個查詢,每個查詢輸入長度爲n的路徑,判斷該路徑是不是TS cycle或者TS simple cycle並輸出題目要求的對應信息。算法

算法思路:

咱們使用鄰接矩陣G保存該圖的邊權,而後使用path數組保存每一次查詢的路徑,判斷該路徑是不是TS cycle和TS simple cycle的方法以下:數組

  • 一、使用 set differentVertices集合保存全部路徑上的不一樣頂點數目,total_dist爲路徑長度,frequencyOfStart爲起點出現的次數,isNa標記路徑是否連通。
  • 二、遍歷路徑上每個頂點,累加total_dist的邊權並判斷當前邊權是否爲0,若是是,說明該路徑不連通,isNa = true,並統計起點出現的次數。
  • 三、首先判斷isNa是否爲true,若是是說明當前路徑不連通,必定不是cycle,輸出printf("Path %d: NA (Not a TS cycle)n",i);若是不是轉4
  • 四、判斷起點和終點是否同樣,若是不同,說明該路徑不是cycle,輸出printf("Path %d: %d (Not a TS cycle)n",i,total_dist);不然轉5
  • 五、判斷differentVertices的大小(路徑中出現的不一樣頂點數目)是否等於N,若是不是,說明沒有訪問每個城市,不是TS cycle或者TS simple cycle,輸出printf("Path %d: %d (Not a TS cycle)n",i,total_dist);不然轉6
  • 六、判斷頂點出現了幾回,若是是2次,說明是TS simple cycle,輸出printf("Path %d: %d (TS simple cycle)n",i,total_dist);不然是TS cycle,輸出printf("Path %d: %d (TS cycle)n",i,total_dist);同時在此狀況下,得更新TS cycle或者TS simple cycle的最小路徑長度和編號。

注意點:

  • 一、只有在判斷當前路徑是TS cycle或者TS simple cycle的時候才能進行更新最小路徑長度

提交結果:

image.png

AC代碼:

#include<cstdio>
#include<vector>
#include<unordered_set>

using namespace std;

int N,M;// 頂點數目和邊數
int G[205][205];// 鄰接矩陣,存儲邊權,不存在爲0

int main(){
    scanf("%d %d",&N,&M);
    int a,b,dist;
    for (int i = 0; i < M; ++i) {
        scanf("%d %d %d", &a, &b, &dist);
        G[a][b] = G[b][a] = dist;
    }
    int K,num,city;
    scanf("%d",&K);
    int min_dis = 0x3fffffff;
    int min_dis_index = -1;
    for(int i=1;i<=K;++i){
        scanf("%d",&num);
        vector<int> path;
        unordered_set<int> differentVertices;// 路徑中不一樣頂點的數目
        for (int j = 0; j < num; ++j) {
            scanf("%d",&city);
            path.push_back(city);
        }
        // 得到路徑長度和起點出現的次數
        int total_dist = 0;
        int frequencyOfStart = 0;
        bool isNa = false;
        for (int k = 0; k < path.size(); ++k) {
            differentVertices.insert(path[k]);
            if(k<path.size()-1){
                total_dist += G[path[k]][path[k+1]];
                if(G[path[k]][path[k+1]]==0) {
                    // 存在沒法到達的邊
                    isNa = true;
                }
            }
            if(path[k]==path[0]){
                ++frequencyOfStart;
            }
        }
        if(isNa){
            // 當前路徑不連通,必定不是cycle
            printf("Path %d: NA (Not a TS cycle)\n",i);
        } else {
            // 必定連通
            if(path[0]!=path[path.size()-1]){
                // 起點和終點不同,不是cycle
                printf("Path %d: %d (Not a TS cycle)\n",i,total_dist);
            } else {
                // 必定是cycle,起點至少出現了2次
                if(differentVertices.size()!=N){
                    // 沒有訪問每個城市,不是TS cycle或者TS simple cycle
                    printf("Path %d: %d (Not a TS cycle)\n",i,total_dist);
                } else {
                    // 必定是TS cycle或者TS simple cycle
                    if(min_dis>total_dist){
                        // 更新最短距離和編號
                        min_dis_index = i;
                        min_dis = total_dist;
                    }
                    if(frequencyOfStart==2){
                        // 頂點只出現了2次且訪問了每個城市,是TS simple cycle
                        printf("Path %d: %d (TS simple cycle)\n",i,total_dist);
                    } else{
                        // 頂點出現大於2次且訪問了每個城市,是TS cycle
                        printf("Path %d: %d (TS cycle)\n",i,total_dist);
                    }
                }
            }
        }
    }
    printf("Shortest Dist(%d) = %d",min_dis_index,min_dis);
    return 0;
}
相關文章
相關標籤/搜索