PAT A1150 Travelling Salesman Problem (25point(s))

PAT A1150 Travelling Salesman Problem

在这里插入图片描述

Sample Input:

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

Sample Output:

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
  • 关键:
    returns to the origin city

  • 思路 1:
    理解题意按情况分类:

  1. 不是一条路径(flag == true):NA (Not a TS cycle)
  2. 是一条路(flag == false, 走得通,不知道有没有走回头路的,我这里按没有,增设了一个vis[]数组)分为:只有是路就输出距离dis
    - 2-1:是环路( a. 点数=边数 b. 头尾同节点)-Ps:Min只在环中求(不考虑没遍历所有城市的路径)
    - 2-1-1:是简单环,节点不重复(节点数==总城市数)(TS simple cycle)
    - 2-1-2:不是简单环 (TS cycle)
    - 2-2:不是环路:(Not a TS cycle)
  • code 1:
#include <bits/stdc++.h>
using namespace std;
const int maxn = 300;
const int INF = 0x3fffffff;
int n, m;
int G[maxn][maxn], path[maxn];
bool vis[maxn];

int main(){
	int c1, c2, k, nC, tmpC;
	scanf("%d %d", &n, &m);
	fill(G[0], G[0]+maxn*maxn, INF);
	for(int i = 0; i < m; ++i){
		scanf("%d %d", &c1, &c2);
		scanf("%d", &G[c1][c2]);
		G[c2][c1] = G[c1][c2];
	}
	scanf("%d", &k);
	int Min = INF, ans = -1;
	for(int i = 1; i <= k; ++i){
		scanf("%d", &nC);
		unordered_set<int> ve;
		for(int j = 0; j < nC; ++j){
			scanf("%d", &path[j]);
			ve.insert(path[j]);
		}
		int dis = 0;
		bool flag = false;
		fill(vis, vis+maxn, false);
		for(int j = 1; j < nC; ++j){
			vis[j-1] = true;
			if(vis[j] == false && G[path[j-1]][path[j]] != INF){
				dis += G[path[j-1]][path[j]];
			}else flag = true;
		}
		printf("Path %d: ", i);
		if(flag){	//1. 不一条路径 
			printf("NA (Not a TS cycle)\n");
		}else{	//2.是一条路径 
			printf("%d ", dis);
			if(ve.size() == n && path[0] == path[nC-1]){	//2-1是cycle 
				if(ve.size() == nC-1){	//2-1-1:simple 
					 printf("(TS simple cycle)\n");
				}else printf("(TS cycle)\n");	//2-1-2 nonsimple 
				if(dis < Min){
					Min = dis;
					ans = i;
				}
			}else printf("(Not a TS cycle)\n"); 	//2-2不是cycle 
		} 
	}
	printf("Shortest Dist(%d) = %d\n", ans, Min);
	return 0;	
} 
  • T2 code:
#include <bits/stdc++.h>
using namespace std;
const int maxn = 510, INF = 0x3fffffff;
int G[maxn][maxn];

int main(){
	int nv, ne;
	scanf("%d %d", &nv, &ne);
	for(int i = 0; i < ne; ++i){
		int c1, c2, td;
		scanf("%d %d %d", &c1, &c2, &td);
		G[c1][c2] = G[c2][c1] = td;
	}
	int nq, min_path, min_dis = INF;
	scanf("%d", &nq);
	for(int i = 1; i <= nq; ++i){
		int qnv, first, pre, now, sum_dis = 0;
		scanf("%d", &qnv);
		bool connect = true;
		unordered_set<int> st;
		for(int j = 0; j < qnv; ++j){
			scanf("%d", &now);
			if(j == 0) first = now;
			else if(G[pre][now] != 0) sum_dis += G[pre][now];
			else connect = false;
			st.insert(now);
			pre = now;
		}
		printf("Path %d: ", i);
		if(connect){
			printf("%d ", sum_dis);
			if(first == now && st.size() == nv){
				if(qnv == nv + 1){
					printf("(TS simple cycle)\n");
				}else{
					printf("(TS cycle)\n");				
				} 
				if(sum_dis < min_dis){
					min_dis = sum_dis;
					min_path = i;
				}
			}else{
				printf("(Not a TS cycle)\n");
			}
		}else{
			printf("NA (Not a TS cycle)\n");
		}
	}
	printf("Shortest Dist(%d) = %d", min_path, min_dis);
	return 0;
}
  • T3 code:
#include <bits/stdc++.h>
using namespace std;
const int maxn = 220;
int G[maxn][maxn];

int main()
{
    int n, m;
    scanf("%d %d", &n, &m);
    for(int i = 0; i < m; ++i)
    {
        int c1, c2, dis;
        scanf("%d %d %d", &c1, &c2, &dis);
        G[c1][c2] = G[c2][c1] = dis;
    }
    int q, min_dis = INT_MAX, min_path = 0;
    scanf("%d", &q);
    for(int i = 1; i <= q; ++i)
    {
        int nq, first, last, pre, sum_dis = 0;
        bool flg = true;
        scanf("%d", &nq);
        unordered_set<int> st;
        for(int j = 0; j < nq; ++j)
        {
            scanf("%d", &last);
            if(j == 0) first = last;
            else
            {
                if(G[pre][last] == 0) flg = false;
                else sum_dis += G[pre][last];
            }
            pre = last;
            st.insert(last);
        }
        printf("Path %d: ", i);
        if(flg)
        {
            printf("%d ", sum_dis);
        }else printf("NA ");
        if(st.size() == n && last == first && flg)
        {
            if(sum_dis < min_dis)
            {
                min_dis = sum_dis;
                min_path = i;
            }
            printf("%s\n", nq == n + 1 ? "(TS simple cycle)" : "(TS cycle)");
        }else printf("(Not a TS cycle)\n");
    }
    printf("Shortest Dist(%d) = %d", min_path, min_dis);
    return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值