1

题目大意:

给定一个N个顶点和M条边的无向图,K个查询,每一个查询输入长度为n的路径,判断该路径是否是TS cycle或者TS simple cycle并输出题目要求的对应信息。

算法思路:

我们使用邻接矩阵G保存该图的边权,然后使用path数组保存每一次查询的路径,判断该路径是否是TS cycle和TS simple cycle的方法如下:

  • 1、使用 set differentVertices集合保存所有路径上的不同顶点数目,total_dist为路径长度,frequencyOfStart为起点出现的次数,isNa标记路径是否连通。
  • 2、遍历路径上每一个顶点,累加total_dist的边权并判断当前边权是否为0,如果是,说明该路径不连通,isNa = true,并统计起点出现的次数。
  • 3、首先判断isNa是否为true,如果是说明当前路径不连通,一定不是cycle,输出printf("Path %d: NA (Not a TS cycle)n",i);如果不是转4
  • 4、判断起点和终点是否一样,如果不一样,说明该路径不是cycle,输出printf("Path %d: %d (Not a TS cycle)n",i,total_dist);否则转5
  • 5、判断differentVertices的大小(路径中出现的不同顶点数目)是否等于N,如果不是,说明没有访问每一个城市,不是TS cycle或者TS simple cycle,输出printf("Path %d: %d (Not a TS cycle)n",i,total_dist);否则转6
  • 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的最小路径长度和编号。

注意点:

  • 1、只有在判断当前路径是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;
}


乔梓鑫
569 声望17 粉丝

主要分享个人学习经验和心得