题解:P15166 [SWERC 2022] Parmigiana With Seafood
P15166 [SWERC 2022] Parmigiana With Seafood
link
呜呜呜好神奇的题。
考虑二分答案,我们把
我们来刻画一下先手/后手获胜的条件。如果有一个
-
- 存在
1 点(u, v) ,\operatorname{dis}(u, v)\bmod 2=1 ,那么(u, v) 形成的虚树满足条件 - 存在
1 点(u, v, w) ,它们的中心为x ,u,v,w 到x 的距离都是偶数,那么(u, v, w) 形成的虚树满足条件。
可以证明上面三条囊括了所有情况。此时我们不需要再二分答案,直接维上面几种情况
#include<bits/stdc++.h>
using namespace std;
#define rep(i, j, k) for(int i=(j); i<=(k); ++i)
#define per(i, j, k) for(int i=(j); i>=(k); --i)
const int N=1e5+3;
int n, d[N], dep[N], ans, f[N];
vector<int> G[N];
void dfs(int u, int pre){
vector<int> d;
if(!dep[u]) f[u]=u;
else ans=max(ans, u);
for(auto v:G[u]) if(v!=pre){
dep[v]=!dep[u];
dfs(v, u);
f[u]=max(f[u], f[v]);
d.emplace_back(f[v]);
}
sort(d.begin(), d.end(), greater<int>());
if(!pre && d.size()>=3) ans=max(ans, d[2]);
else if(pre && d.size()>=2 && !dep[u]) ans=max(ans, d[1]);
}
signed main(){
cin.tie(0)->sync_with_stdio(0);
cin>>n;
rep(i, 2, n){
int u, v;
cin>>u>>v;
G[u].emplace_back(v);
G[v].emplace_back(u);
}
rep(i, 1, n) if(G[i].size()==1) ans=max(ans, i);
dfs(n, 0);
if(n%2==0) ans=n;
cout<<ans;
}