数据结构与算法实验2020夏第二批(中国石油大学)
PA6题解报告——旅行商(TSP)
目录
一、题目描述
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;
}