当信息在电脑、交换机之间传递时,每一步只能通过自己传递到自己所连接的另一台电脑或交换机。请问,电脑与电脑之间传递消息、或者电脑与交换机之间传递消息、或者交换机与交换机之间传递消息最多需要多少步。
第二行包含 n - 1个整数,分别表示第2、3、……、 n台交换机所连接的比自己上一层的交换机的编号。第 i台交换机所连接的上一层的交换机编号一定比自己的编号小。
第三行包含 m个整数,分别表示第1、2、……、 m台终端电脑所连接的交换机的编号。
1 1 3
2 1
![](https://i-blog.csdnimg.cn/blog_migrate/46fa6ce51dd613e7a13df5feedd99436.png)
其中电脑1与交换机4之间的消息传递花费的时间最长,为4个单位时间。
1 2 2
3 4 4 4
![](https://i-blog.csdnimg.cn/blog_migrate/b85d2d7f9f955ad5601fc56b6bc351b8.png)
其中电脑1与电脑4之间的消息传递花费的时间最长,为4个单位时间。
前50%的评测用例满足: n ≤ 20, m ≤ 20。
前70%的评测用例满足: n ≤ 100, m ≤ 100。
所有评测用例都满足:1 ≤ n ≤ 10000,1 ≤ m ≤ 10000。
解題思路
根據題目所給出的關係建立鄰接圖(這裏分為了front和back表示層級關係,但其實合併在一起也可以),選擇第一個電腦終端結點A,以向量記錄A到其他結點的代價(這裏用深度優先搜索算法所得),找出到逹該點代價最高的一結點B,再計算一遍B到其他結點的代價,代價最高的則為答案。
節點A可以選擇任一點,目的是找出代價最高的一點B,再從B找出代價最高者。
代碼
#include <bits/stdc++.h>
using namespace std;
vector<int> dist;
class Point {
public:
int front;
vector<int> back;
bool step;
Point(int f) {
front = f;
step = false;
}
};
void loop (int s, vector<Point>& v, int count) {
v[s].step = true;
count++;
dist[s] = count;
int target = v[s].front;
if (target != -1 && v[target].step == false) {
loop(target,v,count);
}
for (int i = 0; i < v[s].back.size(); i++) {
target = v[s].back[i];
if (v[target].step == false) {
loop(target,v,count);
}
}
}
int main() {
vector<Point> v;
int n, m;
cin >> n >> m;
Point p1(-1);
v.push_back(p1);
v.push_back(p1);
for (int i = 0; i <= n+m; i++) {
dist.push_back(0);
}
for (int i = 2; i <= n; i++) {
int a;
cin >> a;
Point p(a);
v.push_back(p);
v[a].back.push_back(i);
}
for (int i = 1; i <= m; i++) {
int a;
cin >> a;
Point p(a);
v.push_back(p);
v[a].back.push_back(i+n);
}
vector<Point> v2;
v2 = v;
v2[1+n].step = true;
loop(v2[1+n].front,v2,0);
int big = 0, target = 0;
for (int i = 0; i < dist.size(); i++) {
if (dist[i] > big) {
big = dist[i];
target = i;
}
}
for (int i = 0; i <= n+m; i++) {
dist.push_back(0);
}
v2 = v;
v2[target].step = true;
loop(v2[target].front,v2,0);
big = 0;
for (int i = 0; i < dist.size(); i++) {
if (dist[i] > big) {
big = dist[i];
}
}
cout << big << endl;
return 0;
}