旅行商问题

【题目来源】
https://www.acwing.com/problem/content/description/1645/

【问题描述】
“旅行商问题”是这样一个问题:“给出一个城市列表以及每对城市之间的距离,访问每个城市并返回原城市的最短路线是什么?”。
这是组合优化中的一个 NP 难题,在运筹学和理论计算机科学中十分重要。

【输入格式】
第一行包含两个整数 N 和 M,分别表示城市数量以及 无向图 中边的数量。
接下来 M 行,每行以 City1 City2 Dist 格式描述一条边,其中城市编号从 1 到 N,Dist 为正且不超过 100。
再一行包含一个整数 K,表示给定路径的数量。
接下来 K 行描述路径,格式为:n C1 C2 … Cn
n 表示给定路径经过的城市的数目,Ci 是路径中经过的城市的编号。

【输出格式】
对于每个路径,在一行中输出 Path X: TotalDist (Description)
其中 X 是路径编号(从 1 开始),TotalDist 表示路径总距离(如果距离不存在,则输出 NA),Description 是下列中的一项:
• TS simple cycle,如果这是一个访问每个城市的简单回路。
• TS cycle,如果这是一个访问每个城市的回路,但不是简单回路。
• Not a TS cycle,如果这不是一个访问了每个城市的回路。
最后一行,输出 Shortest Dist(X) = TotalDistX 是最接近旅行商问题解决方案的回路编号,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

【输出样例】

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

【算法代码】
代码来源于:https://www.acwing.com/solution/content/96010/

#include <bits/stdc++.h>
using namespace std;

const int N=210,INF= 0x3f3f3f3f;
int n,m;
int ver[N];
int dist[N][N];
bool st[N];

int main() {
    cin>>n>>m;
    memset(dist,0x3f,sizeof dist);
    for(int i=0; i<m; i++) {
        int a,b,c;
        cin>>a>>b>>c;
        dist[a][b]= dist[b][a]=c;
    }

    int k;
    cin>>k;
    int min_dist=INF,min_id;

    for(int T=1; T<=k; T++) {
        int cnt;
        cin>>cnt;
        for(int i=0; i<cnt; i++) cin>>ver[i];

        int sum = 0;
        bool success=true;

        memset(st,0,sizeof(st));

        for(int i=0; i+1<cnt; i++) {
            int idx=ver[i],idx1=ver[i+1];
            if(dist[idx][idx1]==INF) {
                sum=-1;
                success=false;
                break;

            }
            sum+=dist[idx][idx1];
            st[idx]=true;
        }

        for(int i=1; i<=n; i++)
            if(!st[i]) {
                success=false;
                break;
            }

        if(ver[0]!=ver[cnt-1]) success=false;
        if(sum==-1)cout<<"Path "<<T<<": NA (Not a TS cycle)"<<endl;
        else {
            if(!success)cout<<"Path "<<T<<": "<<sum<<" (Not a TS cycle)"<<endl;
            else {
                if(cnt==n+1)cout<<"Path "<<T<<": "<<sum<<" (TS simple cycle)"<<endl;
                else cout<<"Path "<<T<<": "<<sum<<" (TS cycle)"<<endl;

                if(sum<min_dist)min_dist=sum,min_id=T;
            }
        }
    }
    cout<<"Shortest Dist("<<min_id<<") = "<<min_dist<<endl;
    return 0;
}

/*
in:
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

out:
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
*/







 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值