pta天梯专栏
7-11 龙龙送外卖 - SMU 2024 spring 天梯赛1(补题) (pintia.cn)
题解:首先我们先建个图然后存一下各个节点的父亲节点
我们细看这个最短路可以发现,当全部节点加进来,那么最短路就是每一个节点跑两遍然后最深的那个节点最后才跑,这样就只需要1遍
所以我们首先把每一个节点的深度算出来,然后分别记录
然后我们一个个把需要用到的点加进来,从这个节点向上跑到根节点或者跑到之前跑过的点记录答案即可,
如果这点跑过,直接输出答案即可ans-ma+1
ma是最大的深度
#include <bits/stdc++.h> //#pragma GCC optimize("Ofast") #include <iostream> #include <cstdio> #include <cstring> #include <algorithm> #include <queue> #include <cmath> //#define double long double #define int long long #define endl '\n' using namespace std; const int N=1e5+9,M=1e1; const int INF = 0x3f3f3f3f; const int mod=1e9+7; typedef pair<int,int> PII; int kmp(int a,int k,int p) { int ans=1; while (k) { if(k&1) ans=ans*a%p; k>>=1; a=a*a; } return ans; } vector<int> a[N]; int fa[N]; int dep[N]; bool st[N]; int ans; int root=0; void dfs1(int u,int de) { dep[u]=de; for(auto i:a[u]) { dfs1(i,de+1); } } void dfs2(int u) { if(st[u] || u==root) return; st[u]= true; ans+=2; dfs2(fa[u]); } void solve() { int n,m; cin>>n>>m; for(int i=1;i<=n;i++) { int x; cin>>x; if(x==-1) { root=i; fa[i]=i; } else { a[x].push_back(i); fa[i]=x; } } dfs1(root,1); int ma=-1; while (m--) { int x; cin>>x; if(st[x]) cout<<ans-ma+1<<endl; else { ma=max(ma,dep[x]); dfs2(x); cout<<ans-ma+1<<endl; } } } signed main(){ std::ios::sync_with_stdio(false); std::cin.tie(nullptr); int T=1; // cin>>T; while(T--){ solve(); } return 0; }
标签:开学,int,二周,fa,补题,ans,include,root,节点 From: https://www.cnblogs.com/whatdo/p/18068881