[ABC368D] Minimum Steiner Tree题解
题解
题目传送门
分析
要解决这题,我们可以用一个数组
我们再用一个数组
最后统计答案时,只要统计满足
AC Code
#include <bits/stdc++.h>
#define int long long
using namespace std;
const int N = 2e5 + 10;
int n,k,v[N],p[N],d[N];
vector<int> es[N];
bool flag[N],points[N],vst[N];
int cnt[N],cntp[N];
void dfs(int u,int fa)
{
p[u] = fa; d[u] = d[fa] + 1; cntp[u] = points[u];
for(int i = 0,v;i < es[u].size();i++)
{
v = es[u][i];
if(v == fa) continue;
dfs(v,u);
cntp[u] += cntp[v];
}
}
int search(int u)
{
if(vst[u]) return cnt[u];
vst[u] = true;
if(es[u].size() == 1 && es[u][0] == p[u]) return cnt[u] = points[u];
if(cntp[u] == 0) return cnt[u] = 0;
int sum = 1;
for(int i = 0,v;i < es[u].size();i++)
{
v = es[u][i];
if(v == p[u]) continue;
sum += search(v);
}
return cnt[u] = sum;
}
void solve()
{
cin >> n >> k;
for(int i = 1,u,v;i < n;i++) { cin >> u >> v; es[u].push_back(v); es[v].push_back(u); }
for(int i = 1;i <= k;i++) cin >> v[i],points[v[i]] = true;
dfs(1,0);
search(1);
int minn = n;
for(int i = 1;i <= n;i++)
if(cntp[i] == k) minn = min(minn,cnt[i]);
cout << minn << endl;
}
signed main()
{
ios::sync_with_stdio(false);
cin.tie(0); cout.tie(0);
int T = 1;
// cin >> T;
while(T--) solve();
return 0;
}
Atcoder提交记录