n<=2e5,求出最小代價及相應的點集.
標記邊方向後 建立有根無向的樹,dfs算出f[1],
因爲fa,u的f值只差(fa,u)這條邊的方向,所以fa和son的f值相差正負1,自頂向下DP一次即可
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=4e5+20;
map<int,int> mp[N];
vector<int> e[N];
int f[N];
void dfs(int u,int fa)
{
f[u]=0;
for(int i=0;i<e[u].size();i++)
{
int v=e[u][i];
if(v==fa)
continue;
dfs(v,u);
f[u]+=f[v];
if(mp[u][v]==0)
f[u]++;
}
}
void dfs2(int u,int fa)
{
for(int i=0;i<e[u].size();i++)
{
int v=e[u][i];
if(v==fa)
continue;
if(mp[u][v])
f[v]=f[u]+1;
else
f[v]=f[u]-1;
dfs2(v,u);
}
}
int main()
{
int n;
while(cin>>n)
{
int u,v;
for(int i=1;i<=n-1;i++)
{
scanf("%d%d",&u,&v);
mp[u][v]=1;
e[u].push_back(v);
e[v].push_back(u);
}
dfs(1,0);
dfs2(1,0);
int mn=2e5;
for(int i=1;i<=n;i++)
mn=min(mn,f[i]),e[i].clear(),mp[i].clear();
cout<<mn<<endl;
for(int i=1;i<=n;i++)
if(f[i]==mn)
printf("%d ",i);
printf("\n");
}
return 0;
}