cf219d 基础换根法
Posted zsben991126
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了cf219d 基础换根法相关的知识,希望对你有一定的参考价值。
/*树形dp换根法*/ #include<bits/stdc++.h> using namespace std; #define maxn 200005 struct Edge{int to,nxt,flag;}edge[maxn<<1]; int root,n,s,t,head[maxn],tot,dp[maxn]; void init(){ memset(head,-1,sizeof head); tot=0; } void addedge(int u,int v,int flag){ edge[tot].to=v;edge[tot].nxt=head[u];edge[tot].flag=flag; head[u]=tot++; } void dfs1(int u,int pre){ for(int i=head[u];i!=-1;i=edge[i].nxt){ int v=edge[i].to; if(v==pre)continue; if(edge[i].flag==0)dp[u]++; dfs1(v,u); dp[u]+=dp[v]; } } void dfs2(int u,int pre){ for(int i=head[u];i!=-1;i=edge[i].nxt){ int v=edge[i].to; dp[v]=dp[u]+(edge[i].flag==1?1:-1); if(v==pre)continue; dfs2(v,u); } } int main(){ init(); cin>>n; for(int i=1;i<n;i++){ cin>>s>>t; addedge(s,t,1); addedge(t,s,0); } root=1; dfs1(1,0);//第一次dfs求出dp[1] dfs2(1,0);//第二次dfs求出剩下的结点 int ans=99999999; for(int i=1;i<=n;i++)ans=min(ans,dp[i]); cout<<ans<<endl; for(int i=1;i<=n;i++) if(dp[i]==ans)cout<<i<<" "; }
以上是关于cf219d 基础换根法的主要内容,如果未能解决你的问题,请参考以下文章
POJ3585 Accumulation Degree(二次扫描与换根法)
题解 poj3585 Accumulation Degree (树形dp)(二次扫描和换根法)