题目

题目背景
多年以后,我在搬砖的工地上,远远望见了一个身影:仍然是如同漆黑的杆子一般,手丝毫不摆动,而脚一步一印往前挪动,像吸盘,像祂正试图学会在地上平移,用自己的脚。

我几乎要失声叫出祂的名字;这个名字我花了十年去恐惧,花了十年去遗忘,但我看到祂的一瞬间,所有努力都是徒劳,所有意义都被抹杀。

任何事物都逃不过祂的眼睛。当我从惊慌中挣脱出来,抬头便遇上祂的审视。祂胸前的金牌扰乱着我的神志。我只能勉强从牙缝中挤出来几个字:

普……普林斯普!”

祂的嘴唇没有动,我的脑海中却响起一句话。这真的是我刚刚所顿悟的么?

校长笑话,烟雾弹也;水群摆烂,麻痹对手尔。”

回忆如波涛翻滚。仿佛有无数个祂同时在我耳边低语:

你看,你又被骗了吧。”

题目描述
给出一个无向连通图 G=(V,E)G=(V,E)G=(V,E),定义新图 G′=(V,E′)G'=(V,E')G′=(V,E′) 满足 E′={⟨a,b,ca⟩∣dis(a,b)⩽da}E'=\{\langle a,b,c_a\rangle\mid\text{dis}(a,b)\leqslant d_a\}E′={⟨a,b,ca​⟩∣dis(a,b)⩽da​},其中 ⟨a,b,c⟩\langle a,b,c\rangle⟨a,b,c⟩ 表示边权为 ccc 的 a→ba\to ba→b 有向边,而 dis(a,b)\text{dis}(a,b)dis(a,b) 为 GGG 上 a,ba,ba,b 最短路的边数。

求新图 G′G'G′ 上 111 号点到每个点的最短路。

数据范围与约定
n⩽2×105∧di∈[1,n]∧ci∈[1,109]∧∣E∣⩽∣V∣+50n\leqslant 2\times 10^5\land d_i\in[1,n]\land c_i\in[1,10^9]\land |E|\leqslant |V|+50n⩽2×105∧di​∈[1,n]∧ci​∈[1,109]∧∣E∣⩽∣V∣+50 。时限 4s\rm 4s4s 。

思路

注意到 ∣E∣⩽∣V∣+50|E|\leqslant|V|+50∣E∣⩽∣V∣+50,考虑建一棵生成树,然后讨论非树边的影响。必要条件是搞懂树边的影响。即,先考虑原图是一棵树的情况。

树上路径问题?类似此题,可以直接点分治优化建图。不需要边分治,因为 dis(y,z)⩽dx−dis(x,z)\text{dis}(y,z)\leqslant d_x-\text{dis}(x,z)dis(y,z)⩽dx​−dis(x,z) 是 x→yx\to yx→y 有边的充分条件,即 dis(x,y)\text{dis}(x,y)dis(x,y) 可以实际上不经过 zzz,不需要边分治来保障 “必须经过” 的要求。

当然,现在想想,优化建图跑最短路,不如 OUYE\sf OUYEOUYE 所说 数据结构优化转移。建出显式图,只会增加不必要的时空复杂度。非最短路问题,倒是有可能让代码实现更简单(比如 2-sat\text{2-sat}2-sat 问题)。

非树边呢?相当于转移过程中,需要走过某条非树边。点分治的本质是,考虑 dis\text{dis}dis 必须经过某个点;将每条非树边的任一端点设为 “特殊点”,对经过特殊点的 dis\text{dis}dis 进行转移即可。

显式建图,似乎有 O(nlog⁡n+nk)\mathcal O(n\log n+nk)O(nlogn+nk) 条边,其中 k=∣E∣−∣V∣+1k=|E|-|V|+1k=∣E∣−∣V∣+1 。跑 dijkstra\tt dijkstradijkstra 岂不是 O[nlog⁡nlog⁡(nlog⁡n)]\mathcal O[n\log n\log(n\log n)]O[nlognlog(nlogn)] 了吗?可以类比此题,将 (vi+ci)(v_i+c_i)(vi​+ci​) 放入 heap\tt heapheap 中;显式建图,则其等价于将边权为 000 的连通块进行 bfs\rm bfsbfs 更新。这样可以保证每个点直接得到答案,复杂度 O(nlog⁡n+nk)\mathcal O(n\log n+nk)O(nlogn+nk) 。

代码

#include <cstdio> // JZM yydJUNK!!!
#include <iostream> // XJX yyds!!!
#include <algorithm> // XYX yydLONELY!!!
#include <cstring> // (the STRONG LONG for loneliness)
#include <cctype> // DDG yydDOG & ZXY yydBUS !!!
#include <queue>
# define rep(i,a,b) for(int i=(a); i<=(b); ++i)
# define rep0(i,a,b) for(int i=(a); i!=(b); ++i)
# define drep(i,a,b) for(int i=(a); i>=(b); --i)
typedef long long llong;
inline int readint(){int a = 0, c = getchar(), f = 1;for(; !isdigit(c); c=getchar())if(c == '-') f = -f;for(; isdigit(c); c=getchar())a = (a<<3)+(a<<1)+(c^48);return a*f;
}const int MAXN = 200005, MAXM = 200055;
# define _go(i,x) for(int i=head[x]; ~i; i=e[i].nxt)
struct Edge{ int to, nxt; };
Edge e[MAXN<<1]; int head[MAXN], cntEdge;
void addEdge(int a, int b){e[cntEdge].to = b, e[cntEdge].nxt = head[a];head[a] = cntEdge ++;
}
const int LOGN = 18;
int siz[MAXN], dep[LOGN][MAXN], fa[MAXN][LOGN];
bool vis[MAXN]; int whole, core;
void findRoot(int x, int pre){siz[x] = 1; int mx = 0;_go(i,x) if((i^1) != pre && !vis[e[i].to]){findRoot(e[i].to,i), siz[x] += siz[e[i].to];mx = std::max(mx,siz[e[i].to]);}if((mx<<1) <= whole && whole <= (siz[x]<<1)) core = x;
}
int *group[MAXN];
int* collect(const int &level, int x, int pre, int* ptr){fa[x][level] = core, *(ptr ++) = x;_go(i,x) if((i^1) != pre && !vis[e[i].to]){dep[level][e[i].to] = dep[level][x]+1;ptr = collect(level,e[i].to,i,ptr);}return ptr;
}
void solve(int x, int level){static int buc[MAXN], tmp[MAXN]; ///< bucket sortfindRoot(x,-1), memset(buc,0,whole<<2);dep[level][core] = 0, collect(level,core,-1,tmp);rep0(i,0,whole) ++ buc[dep[level][tmp[i]]];rep0(i,1,whole) buc[i] += buc[i-1];group[core] = new int[whole+1];*group[core] = core, group[core][whole] = -1;for(int *i=tmp+1; i!=tmp+whole; ++i){int &rnk = buc[dep[level][*i]-1];group[core][rnk ++] = *i;}vis[core] = true;const int _core = core;_go(i,core) if(!vis[e[i].to]){if(siz[e[i].to] > siz[_core])whole = siz[x]-siz[_core];else whole = siz[e[i].to];solve(e[i].to,level+1);}
}void bfs(int *que, int *dis, int x, const int &n){memset(dis+1,-1,n<<2), dis[x] = 0;int *bac = que; *bac = x;for(; que!=bac+1; ++que) // keep releasing_go(i,x=*que) if(!(~dis[e[i].to])){dis[e[i].to] = dis[x]+1;++ bac, *bac = e[i].to;}
}namespace UFS{int fa[MAXN];int find(int a);bool merge(int a, int b);
}
bool bad[MAXN]; int tot;
const int MAXK = 102;
int dis[MAXK][MAXN], que[MAXK][MAXN];
int *que_ptr[MAXK];typedef std::pair<llong,int> PII;
llong ans[MAXN]; extern bool vis[MAXN];
std::priority_queue<PII> pq;
int radius[MAXN], cost[MAXN];
int main(){int n = readint(), m = readint();rep(i,1,n) UFS::fa[i] = i;memset(head+1,-1,n<<2);std::queue< std::pair<int,int> > bad_edge;for(int i=1,a,b; i<=m; ++i){a = readint(), b = readint();if(UFS::merge(a,b))addEdge(a,b), addEdge(b,a);else{bad[a] = bad[b] = true;bad_edge.push(std::make_pair(a,b));}}whole = n, solve(1,0); memset(vis+1,false,n);for(; !bad_edge.empty(); bad_edge.pop()){const std::pair<int,int> &p = bad_edge.front();addEdge(p.first,p.second), addEdge(p.second,p.first);}rep(i,1,n) if(bad[i]) bfs(que[tot],dis[tot],i,n), ++ tot;rep0(i,0,tot) que_ptr[i] = que[i];rep(i,1,n){radius[i] = readint();cost[i] = -readint(); // negated}ans[1] = 0, vis[1] = true;pq.push(PII{cost[1],1});while(!pq.empty()){int x = pq.top().second; pq.pop();rep0(j,0,LOGN) if(fa[x][j]) // existfor(int* &i=group[fa[x][j]]; ~(*i); ++i){if(dep[j][*i]+dep[j][x] > radius[x]) break;if(vis[*i]) continue; // updatedans[*i] = ans[x]+cost[x], vis[*i] = true;pq.push(PII{ans[*i]+cost[*i],*i});}rep0(j,0,tot) for(int* &i=que_ptr[j]; i!=que[j]+n; ++i){if(dis[j][*i]+dis[j][x] > radius[x]) break;if(vis[*i]) continue; // updatedans[*i] = ans[x]+cost[x], vis[*i] = true;pq.push(PII{ans[*i]+cost[*i],*i});}}rep(i,2,n) printf("%lld\n",-ans[i]);return 0;
}int UFS::find(int a){if(a == fa[a]) return a;return fa[a] = find(fa[a]);
}
bool UFS::merge(int a, int b){if(find(a) == find(b)) return false;fa[fa[a]] = fa[b]; return true;
}

[ACNOI2022]《普林斯普的荣光》相关推荐

  1. [ACNOI2021]《普林斯普的余威》

    题目 题目背景 O n e I n D a r k \sf OneInDark OneInDark 站在 O U Y E \sf OUYE OUYE 的面前,接受神的洗礼.汝必先弃置肉身,方可入众神之 ...

  2. 国家对应下拉列表 相应的 js特效

    <!--#include file="conndb.asp"--> <HTML> <HEAD> <TITLE>adwordschin ...

  3. 万字长文详解华为方舟编译器的荣光和使命

    本文由MO编辑部出品,文字超1万,查阅的资料多达上百万文字,并且与华为方舟编译器的专家做过深度访谈.其不仅解析了华为在编译器和手机系统方面做的多年准备,也向读者展现了波澜壮阔的软件产业发展史. 201 ...

  4. 华为新贵!方舟编译器的荣光和使命

    本文由MO编辑部出品,文字超1万,查阅的资料多达上百万文字,并且与华为方舟编译器的专家做过深度访谈.文章高度概括了波澜壮阔的软件产业发展史,解析了华为在编译器和手机系统方面做的多年准备. 2017年5 ...

  5. 惠普与戴尔模仿IBM转型难 消化整合周期长

    兰奇发给宏碁员工的离别信中强调,个人PC业正经历"短暂历史"的"最激进转型".董事长王振堂表态也有些模糊,他首先强调的依然是个人PC的核心地位. 即便是惠普.戴 ...

  6. 【末日血战】上古时代英雄的荣光—— 樱泷 平民配置月度BOSS攻略

    上古时代英雄的荣光-- 樱&泷 平民配置月度BOSS攻略 前言 阵容配置思路 补充阵容 阵容成本分析 BOSS分析 危机四伏系列 500级 安东尼奥 600级 泰德 700级 布森 800级 ...

  7. 2022-2028年中国普鲁兰多糖行业市场分析及投资前景研究报告

    [报告类型]产业研究 [出版时间]即时更新(交付时间约3个工作日) [发布机构]智研瞻产业研究院 [报告格式]PDF版 本报告介绍了普鲁兰多糖行业相关概述.中国普鲁兰多糖行业运行环境.分析了中国普鲁兰 ...

  8. 写《回国驯火记》的那个安普若

    2007/3/27 写<回国驯火记>的那个安普若 http://an.haiguinet.com/ 以前光觉得安普若的 < 回国驯火记>[ <回国驯火记>又名< ...

  9. 普罗米修斯 监控_完美的分布式监控系统——普罗米修斯

    DevOps工程师或SRE工程师,可能都知道Prometheus普罗米修斯.Prometheus于2012年由SoundCloud创建,目前已经已发展为最热门的分布式监控系统.Prometheus完全 ...

最新文章

  1. python构建cnn图片匹配_tensorflow搭建cnn人脸识别训练+识别代码(python)
  2. dhcp动态主机配置协议
  3. VSS介绍和备份技巧
  4. 让MySQL支持Emoji表情 mysql 5.6
  5. VC++ 访问数据库实例详解图解
  6. 验证手机号码归属地_手机号码归属地能否取消? 工信部回复了
  7. 使用Java高速实现进度条
  8. linux下dnw工具安装和使用
  9. webserver入门
  10. oracle linux 图形化,Linux下Oracle 12C R2图形化安装过程
  11. linux single 禁用显卡,告诉你Ubuntu下禁用独显的方法及命令
  12. Java实现下载url视频资源
  13. C# 填充Excel
  14. 初步认识Apache Ignite
  15. 证券分析软件测试面试题,光大证券面试经验
  16. 关于前端一个用于设置渐变色的css代码网站
  17. 最美证件照工作室需要买什么东西
  18. 记录一次Broken Pipe断链问题排查
  19. 最简单的h264/h265/svac和g711封装成ps流符合gb28181过检码流要求
  20. Sequence定义

热门文章

  1. CentOS7和CentOS8 FreeSWITCH 1.10.7 简单图形化界面1--安装脚本
  2. 零基础最详细html和css
  3. 为什么RSA 公钥指数(e=65537)
  4. Xylon学长的小卖部
  5. cat6 万兆_干货:CAT5E超五类、CAT6和CAT6A超六类布线系统性能和应用上的区别
  6. 关于下载《Java程序员,上班那点事儿》的电子版
  7. (01)开发环境准备
  8. Chrome漏洞分析与利用(三)——Issue-1062091漏洞分析
  9. Halcon一维码识别实例
  10. windows许可证即将过期 win10的解决办法