cf 218D

来源:互联网 发布:鲁大师垃圾软件 编辑:程序博客网 时间:2024/05/29 18:58

给出n-1条边,dp[i]为i为根需改变的边数使得i能到达任意一个点。
升序输出最小的dp(i)的下标。

#include<stdio.h>#include<string.h>#include<iostream>#include<vector>#include<algorithm>using namespace std;const int maxn=2*100000+10,inf=1e9;struct node{    int v,w;    node(int _v=0,int _w=0)    {        v=_v;        w=_w;    }};vector<node>e[maxn];vector<int>ans;int dp[maxn];void dfs1(int u,int fa){    dp[u]=0;    for(int i=0;i<e[u].size();i++)    {        int v=e[u][i].v,w=e[u][i].w;        if(v==fa) continue;        dfs1(v,u);        dp[u]+=dp[v]+w;    }}void dfs2(int u,int fa){    for(int i=0;i<e[u].size();i++)    {        int v=e[u][i].v,w=e[u][i].w;        if(v==fa) continue;        dp[v]=dp[u]+(w?-1:1);        dfs2(v,u);    }}int main(){    int n;    while(~scanf("%d",&n))    {        for(int i=1;i<=n;i++)        {            e[i].clear();            ans.clear();        }        for(int i=1;i<n;i++)        {            int u,v;            scanf("%d %d",&u,&v);            e[u].push_back(node(v,0));            e[v].push_back(node(u,1));        }        dfs1(1,-1);        dfs2(1,-1);        int minn=inf;        for(int i=1;i<=n;i++)        minn=min(minn,dp[i]);        printf("%d\n",minn);        for(int i=1;i<=n;i++)        {            if(dp[i]==minn) ans.push_back(i);        }        for(int i=0;i<ans.size();i++)        {            if(i<ans.size()-1) printf("%d ",ans[i]);            else printf("%d\n",ans[i]);        }    }}
0 0
原创粉丝点击