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

P8269 [USACO22OPEN] Visits S

题目传送门

博客传送门

首先,每头牛牛都只有一个拜访对象,所以如果考虑图论建模的话,相当于每个点出度都是 1。这相当于图是个基环树森林(注意不只有一棵基环树),而且每个基环树都是内向基环树。

而且我们注意到有个特殊点,建出来的图是很多个环,就更加坚定了我们往基环树那块考虑的想法。我们把一个基环树的图画出来:

P8269_1_1

(很像你妈妈的钥匙串有木有)

然后转换一下原题的题意。既然决定图论建模了,那原题的 \(a_i\) 就相当于 \(i -> a_i\) 建边,边权是 \(v_i\)。至于排列,其实就是个行动顺序表,问我们如何安排行动顺序会让最终贡献最大。

对于不在环里的节点,显然不断让入度为 0 的点行动是更优的。首先一个点出去拜访以后就不可能回来,其次对于下图的情况,先让连向 \(v\) 的点拜访 \(v\),然后 \(v\) 再去拜访别人,比先让 \(v\) 拜访别人,多了 \(w_1+w_2+\cdots+w_k\) 的贡献。

P8269_2_1

所以对于环外的部分,直接贪心地进行拓扑排序,累加边权即可。

这样我们就只剩下基环树森林里仅存的几个环了。

P8269_3_1

对于一个环来说,显然你是注定无法让它们都能统计贡献的。你可以自己在脑子里想象这些点逐个移动到它的拜访点,然后你就会发现注定有一个点的拜访点已经挪走了。

刚才那一通模拟后你还能得到,如果这个环有 \(m\) 条边,那你一定可以统计 \(m-1\) 条边的贡献,而且这样一定是比 \(m-2\) 条边或者更往下的情况更优。那些情况一定是如下的图所展示的:

P8269_4_1

也就是 1->2,2->3,4->5,3->4,5->1。那你一定不如 1->2,2->3,3->4,4->5,5->1 或是 4->5,5->1,1->2,2->3,3->4 优。

既然这样,那就相当于我们要在这个环上舍弃一条边。贪心一下,我们舍弃这个环上的最小边。这棵基环树的贡献就是它边权的总和减掉被舍弃的边之边权。

注意原图里有多个基环树,也会有多个环,要将它们被舍弃的边求一个 sum,然后统一减掉。

代码:

P8269
#include<bits/stdc++.h>
#define int long long
using namespace std;inline int read(){int x=0,f=1;char c=getchar();while(c<48){if(c=='-') f=-1;c=getchar();}while(c>47) x=(x<<1)+(x<<3)+(c^48),c=getchar();return x*f;
}const int N=1e5+5;
const int inf=1e16;
int n,h[N],tot,in[N],p[N],W[N],vis[N],mi=inf;
queue<int> q;
struct Nahida{int u,v,w,nxt;
}e[N];inline void add(int u,int v,int w){e[++tot]={u,v,w,h[u]};h[u]=tot;in[v]++;
}inline void dfs(int u){vis[u]=1;for(int i=h[u];i;i=e[i].nxt){int v=e[i].v;mi=min(mi,e[i].w);if(vis[v]) continue;dfs(v);}
}signed main(){n=read();int sum=0;for(int i=1;i<=n;i++){int v=read(),w=read();p[i]=v,W[i]=w;sum+=W[i];add(i,v,w);}for(int i=1;i<=n;i++){if(!in[i]){q.push(i);}}int ans=0;while(!q.empty()){int u=q.front();q.pop();int v=p[u];if(in[v]){in[v]--;if(!in[v]){q.push(v);}}}int misum=0;for(int i=1;i<=n;i++){if(in[i]&&!vis[i]){mi=inf;dfs(i);misum+=mi;}}ans=sum-misum;printf("%lld",ans);return 0;
}
http://www.jsqmd.com/news/24940/

相关文章:

  • Luogu P13925 [POKATT 2024] 联合猫国 / The Paw-litical Game 题解 [ 蓝 ] [ 线性 DP ] [ 种类数观察 ]
  • 深入解析:【STM32项目开源】基于STM32的独居老人监护系统
  • CSP-S 41多校 9
  • 【25.10.28】模拟赛
  • CSP-S模拟41
  • Linux双中文编码笔记
  • C++类和对象(1) - 详解
  • 人工智能之编程基础 Python 入门:第二章 Python 的编辑器 VS Code
  • 2019 福建省队集训录
  • AIX multibos bootlist
  • 记录一次nginx能通但是请求一直不了的问题
  • 【嵌入式】PWM DAC的滤波器设计
  • 被称作遗憾之物 爬满了脊骨 又把控了痛楚 被称作无用之物 修筑了唯一的通路
  • neovim在windwos11下snack.nvim的问题
  • 完整教程:Java 集合 “List + Set”面试清单(含超通俗生活案例与深度理解)
  • 禁用 IPython 历史记录 history.sqlite
  • Luogu P7914 [CSP-S 2021] 括号序列 题解 [ 蓝 ] [ 区间 DP ] [ 前缀和优化 ] [ 调试技巧 ]
  • 扩展BaseMapper类 - 详解
  • 《程序员修炼之道:从小工到专家》前五分之二观后感
  • 矩阵快速幂章节笔记(这里主要介绍的是我的错题)
  • 实验二 现代C++编程初体验
  • P5322 [BJOI2019] 排兵布阵
  • 题解:P9292 [ROI 2018] Robomarathon
  • [题解]P5322 [BJOI2019] 排兵布阵
  • 考前打印
  • 申威服务器安装Nacos 2.0.3 RPM包详细步骤(Kylin V10 sw_64架构)​附安装包
  • ZKY精选冲刺省选国赛仿真训练题
  • MySQL 查询与更新语句执行过程深度解析:从原理到实践​ - 指南
  • ZKY精选冲刺省选国赛技巧训练题
  • 逆向基础--编码(001)