传送门 :
思路考虑树形 d p dp dp , 状态表示 d p [ i ] dp[i] dp[i]以 i i i为中心点的最小翻转次数
如果当前点为中心点 , 考虑两个方面 向上走 和 向下走
优先考虑向下走 :
我们可以递归到底层,自下向上的 d p dp dp
d p [ u ] + = d p [ v ] + w dp[u] +=dp[v]+w dp[u]+=dp[v]+w( w w w如果是正边那么设立为 0 0 0否则 1 1 1
然后我们考虑向上走 :
我们考虑
d
p
[
4
]
=
d
p
[
4
]
+
d
p
[
2
]
−
d
p
[
4
]
+
w
?
−
1
:
1
dp[4] = dp[4]+dp[2] -dp[4]+w?-1:1
dp[4]=dp[4]+dp[2]−dp[4]+w?−1:1 当前的节点
4
4
4一定是子树
d
p
[
4
]
dp[4]
dp[4]+往上的集合
d
p
[
2
]
dp[2]
dp[2],减去重复的
d
p
[
4
]
dp[4]
dp[4] 然后对于当前的边,如果是正边,但是对于
4
4
4来说,往上走是反边,所以需要
+
1
+1
+1,否则
−
1
-1
−1
因此 : 状态转移 : 第一次 : (求子树 d p [ u ] = d p [ v ] + w dp[u] =dp[v]+w dp[u]=dp[v]+w 第二次 : (求整个集合 d p [ v ] = d p [ u ] + w ? − 1 : 1 dp[v] = dp[u]+w?-1:1 dp[v]=dp[u]+w?−1:1
Codeconst int N = 4e5+10 , INF = 0x7fffffff;
struct node{
int to,val;
};
vector g[N];
int f[N];
int minn = INF;
void dfs(int u,int fa){
for(auto j : g[u]){
if(j.to !=fa){
dfs(j.to,u);
f[u] += f[j.to] + j.val;
}
}
}
void dfs_up(int u,int fa){
for(auto j : g[u]){
if(j.to != fa){
f[j.to] = f[u] + (j.val?-1:1);
dfs_up(j.to,u);
}
}
}
void solve()
{
int n;cin>>n;
for(int i=1;i>a>>b;
g[a].pb({b,0});
g[b].pb({a,1});
}
dfs(1,0);
dfs_up(1,0);
for(int i=1;i
关注
打赏
最近更新
- 深拷贝和浅拷贝的区别(重点)
- 【Vue】走进Vue框架世界
- 【云服务器】项目部署—搭建网站—vue电商后台管理系统
- 【React介绍】 一文带你深入React
- 【React】React组件实例的三大属性之state,props,refs(你学废了吗)
- 【脚手架VueCLI】从零开始,创建一个VUE项目
- 【React】深入理解React组件生命周期----图文详解(含代码)
- 【React】DOM的Diffing算法是什么?以及DOM中key的作用----经典面试题
- 【React】1_使用React脚手架创建项目步骤--------详解(含项目结构说明)
- 【React】2_如何使用react脚手架写一个简单的页面?