PAT A1150 Travelling Salesman Problem【模拟】

这道题虽然是以TSP问题作为背景,但是不需要任何TSP算法的知识,只要按照题目模拟即可。在做题的时候,最重要的就是要细心,这道题情况有很多种,要把所有的情况都依次划分出来。
我一开始WA了一个点,检查之后,发现是当我判断是否所有的点均被访问的时候,并没有判断1到n的所有点,而是判断了存储路径数组里的点是否被访问过,这样一来,就根本不会有没有访问过的点了。修复了这个问题之后,终于AC了,开心!
代码最下方的注释里面写了那个检查出我的错误的数据。

#include <iostream>
#include<vector>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<map>
#include<cstdlib>
#include<queue>
#include<cstring>
#include<set>
#include<list>
#include<unordered_set>
using namespace  std;
int n,m;
int dis[210][210];
int vis[210];
int main()
{
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++)
        for(int j=1;j<=n;j++)
        {
            if(i!=j)dis[i][j]=-1;
            else dis[i][j]=0;
        }
    for(int i=1;i<=m;i++)
    {
        int x,y,z;
        scanf("%d%d%d",&x,&y,&z);
        dis[x][y]=dis[y][x]=z;
    }
    int k;
    scanf("%d",&k);
    int ans=0x3f3f3f3f,ansid;
    for(int i=1;i<=k;i++)
    {
        printf("Path %d: ",i);
        int total;
        scanf("%d",&total);
        vector<int>v;
        for(int j=1;j<=total;j++)
        {
            int next;
            scanf("%d",&next);
            v.push_back(next);
        }
        int length=0;
        bool isExist=true;
        for(int i=0;i<v.size()-1;i++)
        {
            int cur=v[i];
            int next=v[i+1];
            if(dis[cur][next]!=-1)
            {
                length+=dis[cur][next];
            }
            else{
                isExist=false;
                break;
            }
        }
        if(isExist)
            printf("%d ",length);
        else
        {
            printf("NA (Not a TS cycle)\n");
            continue;
        }

        bool TSP=true;
        if(v.size()<n+1)
        {
            printf("(Not a TS cycle)\n");
            TSP=false;
        }
        else{
            bool visAll=true,isHeadEqualTail=true;
            fill(vis+1,vis+n+1,0);
            for(int j=0;j<v.size();j++)
            {
                vis[v[j]]++;
            }
            for(int j=1;j<=n;j++)
            {
                if(vis[j]==0)
                {
                    visAll=false;
                    break;
                }
            }
            if(v.front()!=v.back())
                isHeadEqualTail=false;
            if(!isHeadEqualTail)
            {
                printf("(Not a TS cycle)\n");
                TSP=false;
            }
            else if(!visAll)
            {
                printf("(Not a TS cycle)\n");
                TSP=false;
            }
            else
            {
                bool isSimple=true;
                for(int j=1;j<v.size()-1;j++)
                {
                    if(vis[v[j]]>1)
                    {
                        isSimple=false;
                        break;
                    }
                }
                if(isSimple)
                    printf("(TS simple cycle)\n");
                else
                    printf("(TS cycle)\n");
            }
        }
        if(isExist&&TSP)
        {
            if(length<ans)
            {
                ans=length;
                ansid=i;
            }
        }

    }
    printf("Shortest Dist(%d) = %d",ansid,ans);
}
/*
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
20
8 1 1 1 1 6 6 6 1
 */
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值