当前位置: 首页 > news >正文

AGC023F 题解

传送门

Description

给定一棵 \(n\) 个点的外向树,每个节点上有一个 \(0/1\) 的权值,求一个节点拓扑序使得节点权值的逆序对个数最小,输出最小值。 \(n \le 2 \times 10^5\)

Solution

首先,对于一个 \(0\) 的节点,可以把其和父亲绑在一起,选了其父亲后立即就选它。

这样可以把整棵树分成若干连通块,每个连通块仅有深度最小的节点为 \(1\) 其余全 \(0\),然后对这些连通块进行拓扑排序。为了使逆序对数最小,显然应该优先让 \(sz\) 大的连通块在序列中排在前面。

然后假了。

因为可能有一个小连通块,后面跟着一个大连通块,但是整个一坨东西选的比较晚导致答案不优。

我们发现拓扑排序本质就是把连通块按照一定次序往根节点上合并。发现连通块可以不和根节点合并,只和父亲所在的连通块合并,这样会先把大连通块与小连通块合并成更优的连通块,使其选的早一些,保证了决策正确性。

现在只需给出大连通块的定义(即排在前面的连通块具有的特征)。将连通块中 \(0\) 的个数记为 \(cnt_0\)\(1\) 的个数记为 \(cnt_1\),那么当前连通块更优当且仅当 \(cnt_1 \times cnt_0'<cnt_0 \times cnt_1'\)。也就是邻项交换的思想。

可以把散点当作连通块进行合并。合并两个连通块时,相当于把一个接在另一个后面,可以直接统计这次合并对答案的贡献。

使用并查集维护 \(cnt_0\)\(cnt_1\),用优先队列维护连通块即可。复杂度 \(O(n \log n)\)

Code

#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=2e5+10;
int n,p[N],ans;
int cnt0[N],cnt1[N];
int fa[N];
bool vis[N];
int find(int x){return (fa[x]==x)?x:fa[x]=find(fa[x]);}
void merge(int x,int y)
{x=find(x),y=find(y);if(x==y)return ;fa[y]=x;ans+=cnt1[x]*cnt0[y];cnt0[x]+=cnt0[y];cnt1[x]+=cnt1[y];cnt0[y]=cnt1[y]=0;
}
struct node
{int num,x,y;bool operator <(const node &t)const{return x*t.y<y*t.x;}
};
priority_queue<node>q;
signed main()
{ios::sync_with_stdio(false);cin.tie(0);cin>>n;for(int i=2;i<=n;i++)cin>>p[i];for(int i=1;i<=n;i++){int x;cin>>x;fa[i]=i;if(x==0)cnt0[i]=1;else cnt1[i]=1;q.push({i,cnt0[i],cnt1[i]});}while(!q.empty()){auto [x,tmp1,tmp2]=q.top();q.pop();if(vis[x])continue;vis[x]=1;if(p[x]==0)continue;int nxt=find(p[x]);merge(nxt,x);q.push({nxt,cnt0[nxt],cnt1[nxt]});}cout<<ans<<"\n";return 0;
}

总结:

  1. 树上的贪心如果过于“目光短浅”,可以使用合并连通块的方式优化决策。
  2. 拓扑序可以通过捆绑节点与其前驱来优化答案。
  3. 邻项交换真的很神奇。
http://www.hskmm.com/?act=detail&tid=16295

相关文章:

  • 个人介绍
  • C#学习2
  • AGC203F 题解
  • 高级的 SQL 查询技巧
  • 25,9.24日报
  • 在台风天找回了生活的本貌
  • 第二周第三天2.3
  • 欧几里得算法
  • Error response from daemon: could not select device driver nvidia with capabilities: [[gpu]]
  • 全内存12306抢票系统设计:基于位运算的高效席位状态管理
  • 第三天
  • adobe illustrator中如何打出度数的上标
  • day003
  • newDay03
  • 9.24总结
  • 常用API
  • 9月24日
  • 2025.9.24总结 - A
  • RAG 检索优化的五种常见手段及实现
  • 课程学习
  • 代码规范与数学之美
  • Day3
  • vant
  • 给自己的网站增加在线客服功能,还能接入智能大模型知识库
  • C_re_10_反汇编代码还原之多媒体指令集
  • Linux中修改主机名并立即生效的完整指南
  • 项目经理最常见的10个管理失误,你中招了吗?
  • 阿里云国际站NAS:阿里云NAS适合我的数据库备份需求吗? - 教程
  • 02020407 EF Core基础07-一对多实体类关系配置插入数据查询数据、设置额外的外键字段