\(\mathcal{Description}\)

  link.

  给定 \(n\) 个点 \(m\) 条边的无向图和一个源点 \(s\)。要求删除一个不同与 \(s\) 的结点 \(u\),使得有最多的点到 \(s\) 的最短距离改变。求出此时最短距离改变的结点的数量。

  \(n\le2\times10^5,m\le3\times10^5\)。

\(\mathcal{Solution}\)

  首先,以 \(s\) 为源点跑一个单源最短路。设 \(s\) 到 \(u\) 的距离为 \(dist_u\)。

  接着枚举所有点 \(u\) 与其一条边 \((u,v)\)。若满足 \(dist_u+\operatorname{cost}(u,v)=dist_v\),则表示该边是 \(v\) 最短路径的一条转移边,将其加入新图 \(G\) 中。

  显然 \(G\) 是有向无环图,所以直接建立支配树,求出子树大小最大的结点即可。

\(\mathcal{Code}\)

#include <queue>
#include <cstdio>
#include <vector>
#include <cstring> #define cost first
#define node second
#define adj( g, u, v ) \
for ( int _eid = g.head[u], v; v = g.to[_eid], _eid; _eid = g.nxt[_eid] ) typedef long long LL;
typedef std::pair<LL, int> pli; const int MAXN = 2e5, MAXM = 6e5, MAXLG = 17;
int n, m, s, dep[MAXN + 5], siz[MAXN + 5], rnk[MAXN + 5], fa[MAXN + 5][MAXLG + 5];
LL dist[MAXN + 5];
std::queue<int> que;
std::vector<int> pre[MAXN + 5];
std::vector<pli> sour[MAXN + 5]; inline int rint () {
int x = 0; char s = getchar ();
for ( ; s < '0' || '9' < s; s = getchar () );
for ( ; '0' <= s && s <= '9'; s = getchar () ) x = x * 10 + ( s ^ '0' );
return x;
} struct Graph {
int ecnt, head[MAXN + 5], to[MAXM + 5], nxt[MAXM + 5], ind[MAXN + 5];
inline void link ( const int s, const int t ) {
++ ind[to[++ ecnt] = t], nxt[ecnt] = head[s], head[s] = ecnt;
pre[t].push_back ( s );
}
} dag, domt; inline int LCA ( int u, int v ) {
if ( dep[u] < dep[v] ) u ^= v ^= u ^= v;
for ( int i = 17; ~ i; -- i ) if ( dep[fa[u][i]] >= dep[v] ) u = fa[u][i];
if ( u == v ) return u;
for ( int i = 17; ~ i; -- i ) if ( fa[u][i] ^ fa[v][i] ) u = fa[u][i], v = fa[v][i];
return fa[u][0];
} inline void calc ( const int u ) {
siz[u] = 1;
adj ( domt, u, v ) calc ( v ), siz[u] += siz[v];
} inline void Dijkstra ( const int s ) {
static bool vis[MAXN + 5] {};
static std::priority_queue<pli, std::vector<pli>, std::greater<pli> > pque;
memset ( dist, 0x3f, sizeof dist ), pque.push ( { dist[s] = 0, s } );
while ( ! pque.empty () ) {
pli p = pque.top (); pque.pop ();
if ( vis[p.node] ) continue;
vis[p.node] = true;
for ( pli e: sour[p.node] ) {
if ( ! vis[e.node] && p.cost + e.cost < dist[e.node] ) {
pque.push ( { dist[e.node] = p.cost + e.cost, e.node } );
}
}
}
} int main () {
n = rint (), m = rint (), s = rint ();
for ( int i = 1, u, v, w; i <= m; ++ i ) {
u = rint (), v = rint (), w = rint ();
sour[u].push_back ( { LL ( w ), v } );
sour[v].push_back ( { LL ( w ), u } );
}
Dijkstra ( s );
for ( int i = 1; i <= n; ++ i ) {
for ( pli e: sour[i] ) {
if ( dist[e.node] == dist[i] + e.cost ) {
dag.link ( i, e.node );
}
}
}
que.push ( s );
int cnt = 0;
for ( int u; ! que.empty (); que.pop () ) {
rnk[++ cnt] = u = que.front ();
adj ( dag, u, v ) if ( ! -- dag.ind[v] ) que.push ( v );
}
for ( int i = 1; i <= cnt; ++ i ) {
int u = rnk[i], f = 0;
if ( ! pre[u].empty () ) f = pre[u][0];
for ( int j = 1; j < ( int ) pre[u].size (); ++ j ) f = LCA ( f, pre[u][j] );
dep[u] = dep[fa[u][0] = f] + 1, domt.link ( f, u );
for ( int j = 1; j <= 17; ++ j ) fa[u][j] = fa[fa[u][j - 1]][j - 1];
}
calc ( s );
int ans = 0;
for ( int i = 1; i <= n; ++ i ) if ( i ^ s ) ans = ans < siz[i] ? siz[i] : ans;
printf ( "%d\n", ans );
return 0;
}

Solution -「CF 757F」Team Rocket Rises Again的更多相关文章

  1. Solution -「CF 1342E」Placing Rooks

    \(\mathcal{Description}\)   Link.   在一个 \(n\times n\) 的国际象棋棋盘上摆 \(n\) 个车,求满足: 所有格子都可以被攻击到. 恰好存在 \(k\ ...

  2. Solution -「CF 1622F」Quadratic Set

    \(\mathscr{Description}\)   Link.   求 \(S\subseteq\{1,2,\dots,n\}\),使得 \(\prod_{i\in S}i\) 是完全平方数,并最 ...

  3. Solution -「CF 923F」Public Service

    \(\mathscr{Description}\)   Link.   给定两棵含 \(n\) 个结点的树 \(T_1=(V_1,E_1),T_2=(V_2,E_2)\),求一个双射 \(\varph ...

  4. Solution -「CF 923E」Perpetual Subtraction

    \(\mathcal{Description}\)   Link.   有一个整数 \(x\in[0,n]\),初始时以 \(p_i\) 的概率取值 \(i\).进行 \(m\) 轮变换,每次均匀随机 ...

  5. Solution -「CF 1586F」Defender of Childhood Dreams

    \(\mathcal{Description}\)   Link.   定义有向图 \(G=(V,E)\),\(|V|=n\),\(\lang u,v\rang \in E \Leftrightarr ...

  6. Solution -「CF 1237E」Balanced Binary Search Trees

    \(\mathcal{Description}\)   Link.   定义棵点权为 \(1\sim n\) 的二叉搜索树 \(T\) 是 好树,当且仅当: 除去最深的所有叶子后,\(T\) 是满的: ...

  7. Solution -「CF 623E」Transforming Sequence

    题目 题意简述   link.   有一个 \(n\) 个元素的集合,你需要进行 \(m\) 次操作.每次操作选择集合的一个非空子集,要求该集合不是已选集合的并的子集.求操作的方案数,对 \(10^9 ...

  8. Solution -「CF 1023F」Mobile Phone Network

    \(\mathcal{Description}\)   Link.   有一个 \(n\) 个结点的图,并给定 \(m_1\) 条无向带权黑边,\(m_2\) 条无向无权白边.你需要为每条白边指定边权 ...

  9. Solution -「CF 599E」Sandy and Nuts

    \(\mathcal{Description}\)   Link.   指定一棵大小为 \(n\),以 \(1\) 为根的有根树的 \(m\) 对邻接关系与 \(q\) 组 \(\text{LCA}\ ...

随机推荐

  1. PowerShell 教程

    随笔分类 - 教程 转载自:https://www.cnblogs.com/XiaoCY/category/1065141.html PowerShell 管道符之Where-Object的使用方法 ...

  2. 如何将Excl内数据导入数据库?

    最近有个Excl表格内的数据需要导入SQL Server数据库内,使用SQL Server Management Studio客户端图形界面操作了一番,步骤还挺多,感觉有必要分享给大家一下,顺便自己也 ...

  3. leetcode 921. 使括号有效的最少添加

    问题描述 给定一个由 '(' 和 ')' 括号组成的字符串 S,我们需要添加最少的括号( '(' 或是 ')',可以在任何位置),以使得到的括号字符串有效. 从形式上讲,只有满足下面几点之一,括号字符 ...

  4. 网络编程-TCP连接的建立与终止

    TCP是一个面向连接的协议.无论哪一方向另一方发送数据之前,都必须先在双方之间建立一条连接. 1.建立连接 请求端(通常称为客户)发送一个 SYN 段指明客户打算连接的服务器的端口,以及初始序号( I ...

  5. 【一个小发现】VictoriaMetrics中:vm-storage的备份文件,无法给单机版使用

    首先导入一个按天的备份: vmrestore-prod \ -configFilePath="/etc/cos/config.ini" \ -credsFilePath=" ...

  6. JUC之Fork/Join框架

    Fork/Join框架和异步 定义: Fork/Join框架是Java 7提供的一个用于并行执行任务的框架,是一个把大任务分割成若干个小任务,最终汇总每个小任务结果后得到大任务结果的框架.类似于递归或 ...

  7. 南屿 带你 走进 vue

    ### Vue > Vue是一个前端js框架,由尤雨溪开发,是个人项目 Vue近几年来特别的受关注,三年前的时候angularJS霸占前端JS框架市场很长时间,接着react框架横空出世,因为它 ...

  8. linux文件权限全面解析

    目录 linux文件权限全面解析 一:linux文件的权限有哪些? 1,权限分为3个部分 2,权限位 3,每一个权限拥有一个数字编号 4,在添加权限的时候,可以将权限加起来 5,linux添加权限命令 ...

  9. 搭建sublime.txt环境结合使用python

    { "cmd": ["python3", "-u", "$file"] }

  10. Springboot +redis+⾕歌开源Kaptcha实现图片验证码功能

    Springboot +redis+⾕歌开源Kaptcha实现图片验证码功能 背景 注册-登录-修改密码⼀般需要发送验证码,但是容易被 攻击恶意调⽤ 什么是短信-邮箱轰炸机 手机短信轰炸机是批.循环给 ...