【PAT】1150 Travelling Salesman Problem (25 分)

#include <bits/stdc++.h>
using namespace std;
#define maxn 210
int n,m,k,tk;
struct node
{
    int v,dist;
};

vector<node> G[maxn];//[1,n]
int kPath[maxn];//[1,tk]
int sid=-1,ss=INT_MAX;

int vis[maxn];
void isTS(int times){
    fill(vis,vis+maxn,0);
    int ans=0,fflag=1,flag=0;
    vis[kPath[1]]=1;
    for(int i=2;i<=tk;i++){
        flag=0;
        for(int j=0;j<G[kPath[i-1]].size();j++){
            if(kPath[i]==G[kPath[i-1]][j].v){
                flag=1;
                ans+=G[kPath[i-1]][j].dist;
                vis[kPath[i]]++;
                break;
            }
        }
        if(flag==0){
            fflag=0;break;
        }
    }

    if(fflag==0){//路径非法->NA
        ans=-1;
    }

    for(int i=1;i<=n;i++){//每个城市都访问了
        if(vis[i]==0){
                fflag=0;
                break;
        }
    }

    if(fflag==1 && kPath[1]==kPath[tk]){//路径合法&每个城市都访问了
        if(vis[kPath[1]]==2)    printf("Path %d: %d (TS simple cycle)\n",times,ans);
        else                    printf("Path %d: %d (TS cycle)\n",times,ans);
    }else{
        if(ans==-1)             printf("Path %d: %s (Not a TS cycle)\n",times,"NA");
        else                    printf("Path %d: %d (Not a TS cycle)\n",times,ans);
    }

    if(fflag==0) ans=-1;
    if(ans!=-1 && ans<ss){
        ss=ans,sid=times;
    }
}

int main(){
    scanf("%d %d",&n,&m);

    int c1,c2,cd;
    for(int i=0;i<m;i++){
        scanf("%d %d %d",&c1,&c2,&cd);
        G[c1].push_back(node{c2,cd});
        G[c2].push_back(node{c1,cd});
    }

    scanf("%d",&k);

    for(int i=0;i<k;i++){
        scanf("%d",&tk);
        for(int t=1;t<=tk;t++){
            scanf("%d",&kPath[t]);
        }
        isTS(i+1);
    }
    
    if(sid!=-1)     printf("Shortest Dist(%d) = %d",sid,ss);

    return 0;
}

//没啥区别,除了求最小path的方式
#include <bits/stdc++.h>
using namespace std;
#define maxn 210
int n,m,k,tk;
struct node
{
    int v,dist;
};

vector<node> G[maxn];//[1,n]
int kPath[maxn];//[1,tk]
int shortPath[maxn*10];//题中没给k范围,如果要存储注意试一下,或者用vector

int vis[maxn];
void isTS(int times){
    fill(vis,vis+maxn,0);
    int ans=0,fflag=1,flag=0;
    vis[kPath[1]]=1;
    for(int i=2;i<=tk;i++){
        flag=0;
        for(int j=0;j<G[kPath[i-1]].size();j++){
            if(kPath[i]==G[kPath[i-1]][j].v){
                flag=1;
                ans+=G[kPath[i-1]][j].dist;
                vis[kPath[i]]++;
                break;
            }
        }
        if(flag==0){
            fflag=0;break;
        }
    }

    if(fflag==0){//路径非法->NA
        ans=-1;
    }

    for(int i=1;i<=n;i++){//每个城市都访问了
        if(vis[i]==0){
                fflag=0;
                break;
        }
    }

    if(fflag==1 && kPath[1]==kPath[tk]){//路径合法&每个城市都访问了
        if(vis[kPath[1]]==2)    printf("Path %d: %d (TS simple cycle)\n",times,ans);
        else                    printf("Path %d: %d (TS cycle)\n",times,ans);
    }else{
        if(ans==-1)             printf("Path %d: %s (Not a TS cycle)\n",times,"NA");
        else                    printf("Path %d: %d (Not a TS cycle)\n",times,ans);
    }

    if(fflag==0) ans=-1;
    shortPath[times]=ans;
}

int main(){
    scanf("%d %d",&n,&m);

    int c1,c2,cd;
    for(int i=0;i<m;i++){
        scanf("%d %d %d",&c1,&c2,&cd);
        G[c1].push_back(node{c2,cd});
        G[c2].push_back(node{c1,cd});
    }

    scanf("%d",&k);

    for(int i=0;i<k;i++){
        scanf("%d",&tk);
        for(int t=1;t<=tk;t++){
            scanf("%d",&kPath[t]);
        }
        isTS(i+1);
    }
    int shortId=-1,shortS=INT_MAX;
    for(int i=1;i<=k;i++){
        if(shortPath[i]!=-1 && shortPath[i]<shortS){
            shortS=shortPath[i];
            shortId=i;
        }
    }
    if(shortId!=-1) printf("Shortest Dist(%d) = %d",shortId,shortS);

    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值