题意:给你一颗n个结点的无向树,然后给你m条路径(a, b),让你求最小的点集,满足这些路径上至少有一点在这个点集上。输出点集的大小和点。
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 1e5+5;
int n,m;
vector<int> G[maxn];
unordered_set<int> s[maxn];
int ok[maxn];
void dfs(int u,int f){
for(auto v : G[u]){
if(v == f) continue;
dfs(v,u);
if(ok[u]) continue;
if(s[u].size() < s[v].size()){
swap(s[u],s[v]);
}
for(auto it : s[v]){
if(s[u].find(it) != s[u].end()){
ok[u] = 1;
break;
}
s[u].insert(it);
}
}
if(ok[u]) s[u].clear();
}
int main(){
//freopen("in.txt","r",stdin);
scanf("%d",&n);
for(int u,v,i=1;i<n;i++){
scanf("%d%d",&u,&v);
G[u].push_back(v);
G[v].push_back(u);
}
scanf("%d",&m);
for(int u,v,i=0;i<m;i++){
scanf("%d%d",&u,&v);
if(u==v) ok[u] = 1;
s[u].insert(i);
s[v].insert(i);
}
dfs(1,0);
vector<int> res;
for(int i=1;i<=n;i++){
if(ok[i]) res.push_back(i);
}
printf("%d\n",res.size());
for(auto it : res){
printf("%d ",it);
}
return 0;
}