codeforces219D
Posted pandaking
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了codeforces219D相关的知识,希望对你有一定的参考价值。
题意: 给出一棵树,但是它的边是有向边,选择一个城市,问最少调整多少条边的方向能使一个选中城市可以到达所有的点,输出最小的调整的边数,和对应的点。
决策最大化的问题,而且是在树上做,想都不用想就是树形dp
然后我没想到的东西是什么呢,没有想到跑两次dfs,而且图的边可以带权值,我都想不到,感觉怎么一点图的建模的思想都没有啊。。。。。。。。。。。
主要看代码吧:
1 #include<bits/stdc++.h> 2 using namespace std; 3 const int maxn=200100; 4 struct node{ 5 int to,w; 6 node(int a,int b){to=a;w=b;} 7 }; 8 vector<node> G[maxn]; 9 vector<int >ans; 10 int dp[maxn],num[maxn],n; 11 12 void dfs1(int u,int fa){ 13 for(int i=0;i<G[u].size();i++){ 14 node now=G[u][i]; 15 if(now.to==fa) continue; 16 int v=now.to,w=now.w; 17 dfs1(v,u); 18 dp[u]=(dp[u]+dp[v]+w); 19 } 20 } 21 22 void dfs2(int u,int fa){ 23 for(int i=0;i<G[u].size();i++){ 24 node now=G[u][i]; 25 if(now.to==fa) continue; 26 if(now.w==1){ 27 num[now.to]=num[u]+1; 28 }else{ 29 num[now.to]=num[u]-1; 30 } 31 dfs2(now.to,u); 32 } 33 } 34 35 int main(){ 36 scanf("%d",&n); 37 for(int i=1;i<n;i++){ 38 int s,e; 39 scanf("%d%d",&s,&e); 40 G[s].push_back(node(e,1)); 41 G[e].push_back(node(s,0)); 42 } 43 dfs1(1,-1); 44 num[1]=n-1-dp[1]; 45 dfs2(1,-1); 46 int tmp=1e9+7; 47 for(int i=1;i<=n;i++){ 48 if(tmp>num[i]){ 49 ans.clear(); 50 tmp=num[i]; 51 ans.push_back(i); 52 }else if(tmp<num[i]){ 53 continue; 54 }else{ 55 ans.push_back(i); 56 } 57 } 58 printf("%d ",tmp); 59 for(int i=0;i<ans.size()-1;i++) printf("%d ",ans[i]); 60 printf("%d ",ans[ans.size()-1]); 61 return 0; 62 }
以上是关于codeforces219D的主要内容,如果未能解决你的问题,请参考以下文章
Codeforces 219D Choosing Capital for Treeland 2次DP
Choosing Capital for Treeland CodeForces - 219D (树形DP)