PA6题解报告——旅行商(TSP)

数据结构与算法实验2020夏第二批(中国石油大学)
PA6题解报告——旅行商(TSP)

目录

  1. 题目描述
  2. 题目分析
  3. 编码实现

一、题目描述

1. 描述

Shrek是一个大山里的邮递员,每天负责给所在地区的n个村庄派发信件。但杯具的是,由于道路狭窄,年久失修,村庄间的道路都只能单向通过,甚至有些村庄无法从任意一个村庄到达。这样我们只能希望尽可能多的村庄可以收到投递的信件。
Shrek希望知道如何选定一个村庄A作为起点(我们将他空投到该村庄),依次经过尽可能多的村庄,路途中的每个村庄都经过仅一次,最终到达终点村庄B,完成整个送信过程。这个任务交给你来完成。

2. 输入

第一行包括两个整数n,m,分别表示村庄的个数以及可以通行的道路的数目。
以下共m行,每行用两个整数v1和v2表示一条道路,两个整数分别为道路连接的村庄号,道路的方向为从v1至v2,n个村庄编号为[1, n]。

3. 输出

输出一个数字,表示符合条件的最长道路经过的村庄数。

4. 例

//输入
4 3
1 4
2 4
4 3

//输出
3
5. 限制

1 ≤ n ≤ 1,000,000
0 ≤ m ≤ 1,000,000
输入保证道路之间没有形成环
时间:2 sec
空间:256 MB

6. 提示

拓扑排序

二、题目分析

代码实现

使用拓扑排序的方法求路径长度最大值,把入度为0的点入队,出队头节点与路径长度取一个最大值,不断重复直至队列为空。

复杂度分析:

  • 时间复杂度: O ( n + m ) O(n+m) O(n+m)
  • 空间复杂度: O ( n + m ) O(n+m) O(n+m)

三、编码实现

说明:
下述代码全部为【数据结构与算法实验 OJ 平台】提交过的代码。

#include "cmath"
#include "cstdio"

using namespace std;

const int MAXSIZE = 1e6 + 5;
const int mod = 1e6 - 5;

struct node
{
    int x, length;
};
node q[MAXSIZE];
int arr[4][MAXSIZE];

void Insert(int x, int y, int *total)
{
    *total = *total + 1;
    arr[0][*total] = y;
    arr[1][*total] = arr[2][x];
    arr[2][x] = *total;
    arr[3][y]++;
}

void Sort(int *max, int n)
{
    int head = 0, tail = 0;
    for (int i = 1; i <= n; i++)
    {
        if (arr[3][i] == 0)
        {
            q[tail] = {i, 1};
            tail = (tail + 1) % mod;
        }
    }
    while (head != tail)
    {
        node x = q[head++];
        head %= mod;
        if (x.length > *max)
            *max = x.length;
        for (int i = arr[2][x.x]; i; i = arr[1][i])
        {
            int y = arr[0][i];
            if (--arr[3][y] == 0)
            {
                q[tail] = {y, x.length + 1};
                tail = (tail + 1) % mod;
            }
        }
    }
}

int main()
{
    int n, m;
    int max = 0;
    int total;
    scanf("%d %d", &n, &m);
    int u, v;
    for (int i = 0; i < m; i++)
    {
        scanf("%d %d", &u, &v);
        Insert(u, v, &total);
    }
    Sort(&max, n);
    printf("%d\n", max);
    return 0;
}
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值