PAT レベル A 1150 巡回セールスマンの問題

元のタイトルへのリンク

「巡回セールスマン問題」とは、「都市のリストと各都市間の距離が与えられた場合、各都市を訪問して元の都市に戻る最短ルートは何ですか?」という問題です。

これは組み合わせ最適化における NP 困難問題であり、オペレーションズ リサーチおよび理論コンピューター サイエンスにおいて非常に重要です。

この問題では、与えられたパスのリストから巡回セールスマン問題の解に最も近いパスを見つけるように求められます。

入力形式
最初の行には 2 つの整数 N と M が含まれており、それぞれ無向グラフの都市の数とエッジの数を表します。

次の M 行では、各行が City1 City2 Dist の形式でエッジを記述します。都市番号は 1 から N で、Dist は正で 100 を超えません。

次の行には、指定されたパスの数を表す整数 K が含まれています。

次の K 行は、次の形式でパスを記述します。

n C1 C2 … Cn n
n は特定のルートが通過する都市の数を表し、Ci はそのルートが通過する都市の数を表します。

出力形式
パスごとに、Path X: TotalDist (説明) を 1 行で出力します。

ここで、X はルート番号 (1 から始まります)、TotalDist はルートの合計距離 (距離が存在しない場合は NA)、説明は次のいずれかです。

あらゆる街を巡るシンプルサイクルならTSシンプルサイクル。
TS サイクルは、すべての都市を訪れるサイクルですが、単純なサイクルではありません。
これがすべての都市を訪れたサイクルでなければ、TS サイクルではありません。
最後の行では、Shortest Dist(X) = TotalDist を出力します。ここで、X は巡回セールスマン問題の解に最も近い回路番号、TotalDist はその合計距離です。

独自のソリューションが保証されます。

データ範囲
2<N≦200、
N−1≦M≦N(N−1)
2、1≦K≦
1000、1≦n≦300
入力例:
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出力例:パス 1: 11 (TS シンプル サイクル) パス2: 13 (TS シンプル サイクル)パス 3: 10 (非パス 4: 8 (TS サイクル)パス5: 3 (TS サイクルではない)パス 6: 13 (TS サイクルではない)パス 7: NA (TS サイクルではない)

















最短距離(4) = 8

私の解決策:

#include <bits/stdc++.h>
using namespace std;
const int N = 210, INF = 0x3f3f3f3f;
int n, m, k;
int d[N][N], vi[310];
bool st[N];
int main(){
    int min_dist = INF;
    int min_id;
    cin >> n >> m;
    memset(d, 0x3f, sizeof d);
    for(int i = 0; i < m; i ++ ){
        int a, b, c;
        cin >> a >> b >> c;
        d[a][b] = d[b][a] = c; 
    }
    cin >> k;
    for(int T = 1; T <= k; T ++ ){
        int sum = 0;
        bool success = true;
        int v;
        cin >> v;
        memset(st, 0, sizeof st);
        for(int i = 1; i <= v; i ++ ) cin >> vi[i];
        for(int i = 1; i + 1 <= v; i ++ ){
            int a = vi[i], b = vi[i + 1];
            if(d[a][b] == INF){
                sum = -1;
                success = false;
                break;
            }
            else{
                st[a] = true;
                sum += d[a][b];
            }
        }
        for(int i = 1; i <= n; i ++ ){
            if(!st[i]){
                success = false;
                break;
            }
        }
        if (vi[1] != vi[v]) success = false;
        
        if(sum == -1){
            printf("Path %d: NA (Not a TS cycle)\n", T);
        } 
        else{
            if(!success){
                printf("Path %d: %d (Not a TS cycle)\n", T, sum);
            }
            else{
                if(v == n + 1) printf("Path %d: %d (TS simple cycle)\n", T, sum);
                else printf("Path %d: %d (TS cycle)\n", T, sum);
                if(sum < min_dist){
                    min_dist = sum;
                    min_id = T;
                }
            }
        }
    }
    printf("Shortest Dist(%d) = %d\n", min_id, min_dist);
    return 0;
}

おすすめ

転載: blog.csdn.net/weixin_45660485/article/details/126046421
おすすめ