一、题目
龙龙送外卖
二、分析
根据贪心思想,最后外卖员的位置应该在距离外卖站最远的送餐地址。
那么最短路程 = 需要经过的边数*2 - max(外卖站到送餐地址)
建树方式:使用f来记录i的父节点
新增送餐点时:
????????搜索新增送餐点到外卖站未被标记的边(我的代码实际是标记节点)
????????搜索新增送餐点到外卖站的长度
注:在写DFS时要加上记忆化搜索和减枝,不然容易超时。
三、代码
#include <bits/stdc++.h>
using namespace std;
const int N = 100010;
int n, m, t;
int f[N];
int DIST;
bool st[N];
int dp[N];
void dfs1(int root, int dist)
{
if (root == t || st[root])
{
DIST += dist;
return;
}
st[root] = true;
dfs1(f[root], dist + 2);
}
int dfs2(int root)
{
if (dp[root] || root == t)
return dp[root];
return dp[root] = dfs2(f[root]) + 1;
}
int main()
{
cin >> n >> m;
for (int i = 1; i <= n; i++)
f[i] = i;
for (int i = 1; i <= n; i++)
{
int x;
cin >> x;
f[i] = x;
if (x == -1)
t = i;
}
int distmax = 0;
while (m--)
{
int x;
cin >> x;
dfs1(x, 0);
distmax = max(distmax, dfs2(x));
cout << DIST - distmax << endl;
}
return 0;
}
|