https://codeforces.com/problemset/problem/1975/D
分析:
观察样例可以发现,对于PB第一次在位置 r 接触到红点之后,接下来的怎么走完全可以有PB说了算,情况不会更差。同时还能发现,大部分边都是需要走两遍的,只有最后一条路径只需要走一遍。所以只需要将距离将距离 r 最长的路径 d 放到最后即可,这部分的步数为 2*(n-1)- d。最终结果应该是:到点 r 的步数 + 2*(n-1)- d。
现在考虑点 r 的位置,可以猜测 r 在 b 到 a 的中点附近。如果 r 在另一个位置,可以将 r 从中点移过去。此时虽然 d 的值可能增 1,但是 d 的值每增 1,PA 和 PB 相遇的时间也会至少增加 1 ,因此答案不会更优。
#include<bits/stdc++.h>
using namespace std;
/*
ios::sync_with_stdio(false);cin.tie(nullptr);cout.tie(nullptr);
*/
// #define int long long
#define ld long double
//#define INT __int128
typedef long long LL;
typedef unsigned long long ULL;
typedef pair<long long, long long> PLL;
typedef pair<int, int> PII;
typedef pair<double, double> PDD;
const LL INF = 0x3f3f3f3f3f3f3f3f;
const int inf = 0x3f3f3f3f;
const LL mod = 1e9 + 7;
const ld eps = 1e-12;
const int N = 5e5 + 10, M = N + 10;
int n;
vector<int>g[N];
int a,b;
struct DIJKSTRA {
// vector<PII>g[M];
int dist[M];
int cur[N];
bool vis[M];
int idx = n;
void init(int u){
idx=u;
}
void dij(int u) {
for (int i = 1; i <= idx; i++)dist[i] = INF, vis[i] = 0,cur[i]=-1;
dist[u] = 0;
priority_queue<PII, vector<PII>, greater<PII>>q;
q.push({ dist[u],u });
while (!q.empty()) {
int t = q.top().second;
q.pop();
if (vis[t])continue;
vis[t] = 1;
for (int i = 0; i < g[t].size(); i++) {
int j = g[t][i], w = 1;
if (dist[j] > dist[t] + w) {
dist[j] = dist[t] + w;
cur[j]=t;
q.push({ dist[j],j });
}
}
}
// return dist[n];
}
}st;
void solve(){
cin>>n;
cin>>a>>b;
for(int i=1;i<=n;i++){
g[i].clear();
}
st.init(n+5);
for(int i=1;i<n;i++){
int u,v;
scanf("%d%d",&u,&v);
g[u].push_back(v);
g[v].push_back(u);
}
st.dij(b);
int d=st.dist[a]/2;
int r=a;
int ans=(st.dist[a]+1)/2+2*(n-1);
// cout<<"_________________"<<d<<" "<<ans<<endl;
while(d&&st.cur[r]!=-1){
r=st.cur[r];
d--;
}
st.init(n+5);
st.dij(r);
int mx=0;
for(int i=1;i<=n;i++){
mx=max(mx,st.dist[i]);
// cout<<"++++ "<<i<<" "<<st.dist[i]<<endl;
}
ans-=mx;
cout<<ans<<endl;
}
signed main(){
// ios::sync_with_stdio(false);cin.tie(nullptr);cout.tie(nullptr);
int T=1,cas=1;
cin>>T;
while(T--){
solve();
}
return 0;
}
1471

被折叠的 条评论
为什么被折叠?



