题意:龙龙送外卖的小区构成了一棵树,外卖站为根节点。每次新增一个点外卖的地址,从外卖站出发,求出访问了所有点了外卖的地方至少一次(这样才能把外卖送到)所需的最短路程的距离.一开始一个地址的外卖都不用送,两个相邻的地点之间的路径长度统一设为 1,且从外卖站出发可以访问到所有地点。
题解: 主要看你能不能找到关键点,即最短路程 等于 经过边的路程 * 2 - 最深点的度数。然后更新添加一个点时经过边的路程和最深点的度数。
代码
#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;
const int N = 1e5+10;
vector<vector<int>> c;//相当于邻接矩阵
bool st[N];//判断点是否添加过
int ma;//路程
int d;//最大深度
int dist[N];//度数
int f[N];//父节点
int bg = 0;//外卖站
void dfs(int u,int len)
{
dist[u] = len;
for(auto it : c[u])
{
dfs(it,len+1);
}
}
void dfs2(int u)
{
if(st[u] || u==bg)return;
st[u]=true;
ma+=2;
dfs2(f[u]);
}
int main()
{
int n,m;
cin>>n>>m;
c.resize(n+1);//比邻接矩阵方便多了 必须要开辟空间
for(int i=1;i<=n;i++)
{
int t;cin>>t;
if(t!=-1){
c[t].push_back(i);
f[i] = t;
}else bg = i,f[i]=i;
}
dfs(bg,0);
while(m--)
{
int t;cin>>t;
if(st[t])cout<<ma-d<<endl;
else{
d = max(d,dist[t]);
dfs2(t);
cout<<ma-d<<endl;
}
}
}