Wannafly挑战赛2 D.Delete(拓扑排序 + dij预处理 + 线段树维护最小值)
题目链接 D.Delete
考虑到原图是个DAG,于是我们可以求出每个点的拓扑序。
然后预处理出起点到每个点的最短路$ds[u]$,
和所有边反向之后从终点出发到每个点的最短路$dt[u]$。
令点$u$的拓扑序为$a(u)$。
对于特定的一条边$(u, v, w)$,相当于给所有拓扑序为$[a(u) + 1, a[v] - 1]$的点贡献了一条总长度为$ds[u] + dt[v] + w$的路径。
我们在询问点$u$的时候找到对$u$点贡献的所有路径中长度最小的即可。
特别地,当$s$无法到达$u$或$u$无法到达t时,输出原图从$s$到$t$的最短路即可。
#include <bits/stdc++.h> using namespace std; #define rep(i, a, b) for (int i(a); i <= (b); ++i)
#define dec(i, a, b) for (int i(a); i >= (b); --i)
#define lson i << 1, L, mid
#define rson i << 1 | 1, mid + 1, R typedef long long LL; const int N = 1e5 + 10;
const LL INF = 1e18; int n, m, s, t, q;
LL ans;
LL ds[N], dt[N];
LL mi[N << 2]; struct node{
int u;
LL w;
friend bool operator < (const node &a, const node &b){
return a.w > b.w;
}
}; vector <node> v[N], g[N];
int a[N], deg[N]; void dij(int s, LL dis[], vector <node> v[]){
priority_queue <node> q;
static bool vis[N];
rep(i, 1, n) dis[i] = 1e18, vis[i] = false;
q.push({s, 0});
dis[s] = 0;
while (!q.empty()){
int u = q.top().u; q.pop();
if (vis[u]) continue;
vis[u] = 1;
for (auto edge : v[u]) if (dis[u] + edge.w < dis[edge.u]){
dis[edge.u] = dis[u] + edge.w;
q.push({edge.u, dis[edge.u]});
}
}
} void getdag(){
queue <int> q;
int cnt = 0;
rep(i, 1, n){
if (deg[i] == 0) a[i] = ++cnt, q.push(i);
} while (!q.empty()){
int x = q.front(); q.pop();
for (auto edge : v[x]){
--deg[edge.u];
if (deg[edge.u] == 0) a[edge.u] = ++cnt, q.push(edge.u);
}
}
} void build(int i, int L, int R){
mi[i] = INF;
if (L == R) return;
int mid = (L + R) >> 1;
build(lson);
build(rson);
} void update(int i, int L, int R, int l, int r, LL val){
if (l <= L && R <= r){
mi[i] = min(mi[i], val);
return;
} int mid = (L + R) >> 1;
if (l <= mid) update(lson, l, r, val);
if (r > mid) update(rson, l, r, val);
} void query(int i, int L, int R, int x, LL &ans){
ans = min(ans, mi[i]);
if (L == R) return;
int mid = (L + R) >> 1;
if (x <= mid) query(lson, x, ans);
else query(rson, x, ans);
} int main(){ scanf("%d%d%d%d", &n, &m, &s, &t);
rep(i, 1, m){
int x, y, z;
scanf("%d%d%d", &x, &y, &z);
v[x].push_back({y, z});
g[y].push_back({x, z});
++deg[y];
} getdag();
dij(s, ds, v);
dij(t, dt, g); build(1, 1, n);
rep(i, 1, n){
for (auto edge : v[i]){
if (a[i] + 1 < a[edge.u] && ds[i] != INF && dt[edge.u] != INF){
update(1, 1, n, a[i] + 1, a[edge.u] - 1, ds[i] + dt[edge.u] + edge.w);
}
}
} scanf("%d", &q);
while (q--){
int x;
scanf("%d", &x);
ans = INF;
if (ds[x] == INF || dt[x] == INF){
printf("%lld\n", dt[s]);
continue;
} query(1, 1, n, a[x], ans);
if (ans == INF) puts("-1");
else printf("%lld\n", ans);
} return 0;
}
Wannafly挑战赛2 D.Delete(拓扑排序 + dij预处理 + 线段树维护最小值)的更多相关文章
- Wannafly挑战赛2_D Delete(拓扑序+最短路+线段树)
Wannafly挑战赛2_D Delete Problem : 给定一张n个点,m条边的带权有向无环图,同时给定起点S和终点T,一共有q个询问,每次询问删掉某个点和所有与它相连的边之后S到T的最短路, ...
- 【拓扑排序】【线段树】Gym - 101102K - Topological Sort
Consider a directed graph G of N nodes and all edges (u→v) such that u < v. It is clear that this ...
- bzoj4383 [POI2015]Pustynia 拓扑排序+差分约束+线段树优化建图
题目传送门 https://lydsy.com/JudgeOnline/problem.php?id=4383 题解 暴力的做法显然是把所有的条件拆分以后暴力建一条有向边表示小于关系. 因为不存在零环 ...
- Wannafly挑战赛10 D 小H的询问(线段树)
题目链接 Problem D 这个题类似 SPOJ GSS3 做过那个题之后其实就可以秒掉这题了. 考虑当前线段树维护的结点 在那道题的基础上,这个题要多维护几个东西,大概就是左端点的奇偶性,右端点 ...
- [luogu3573 POI2014] RAJ-Rally (拓扑排序 权值线段树)
传送门 Solution 在DAG中我们可以\(O(n)\)预处理\(Ds(u)\)表示从u表示以s为起点的最长路\(Dt(u)\)表示以u为终点的最长路,那么经过\((u,v)\)的最长路即为\(D ...
- [BZOJ4552][TJOI2016&&HEOI2016]排序(二分答案+线段树/线段树分裂与合并)
解法一:二分答案+线段树 首先我们知道,对于一个01序列排序,用线段树维护的话可以做到单次排序复杂度仅为log级别. 这道题只有一个询问,所以离线没有意义,而一个询问让我们很自然的想到二分答案.先二分 ...
- 【拓扑 字符串还原 + 线段树维护】奇洛金卡达(father)
奇洛金卡达(father) Description 阿良良木历将要迎来人生(不,是吸血鬼生涯)的第三次战斗——与身为人类的奇洛金卡达在直江津高中的操场solo,以取回Heartunderblade 的 ...
- 2018.08.01 BZOJ4552: [Tjoi2016&Heoi2016]排序(二分+线段树)
传送门 线段树简单题. 二分答案+线段树排序. 实际上就是二分答案mid" role="presentation" style="position: relat ...
- 【BZOJ4552】【HEOI2016】排序 [二分答案][线段树]
排序 Time Limit: 60 Sec Memory Limit: 256 MB[Submit][Status][Discuss] Description 在2016年,佳媛姐姐喜欢上了数字序列 ...
随机推荐
- idea 关于高亮显示与选中字符串相同的内容踩过的坑
由 Eclipse 切换到 idea 遇到了很多不熟的地方和踩过的坑,下面记录 idea 关于高亮显示与选中字符串相同的内容踩过的坑. IDEA 2017.2.1 版本修改 Identifier un ...
- Python语言的简介
___________________________________________________________我是一条分割线__________________________________ ...
- k短路模板
https://acm.taifua.com/archives/jsk31445.html 链接: https://nanti.jisuanke.com/t/31445 #include <io ...
- POJ:2695-The Pilots Brothers' refrigerator
题目链接:http://poj.org/problem?id=2965 The Pilots Brothers' refrigerator Time Limit: 1000MS Memory Limi ...
- Linux优化总结
1)netstat (*****)查看网络状态lntup或an 1.[listening|-l] 2.[--numeric|-n] 3.[--tcp|-t] 4.[--udp|-u] 5[--prog ...
- day08 多线程socket 编程,tcp粘包处理
复习下socket 编程的步骤: 服务端: 1 声明socket 实例 server = socket.socket() #括号里不写 默认地址簇使用AF_INET 即 IPv4 ...
- 解决debian 9 重启nameserver失效问题
目录 解决debian 9 重启nameserver失效问题 安装resolvconf 编辑文件 测试 解决debian 9 重启nameserver失效问题 刚安装完debian9,用过之后会发现/ ...
- python - 接口自动化测试 - contants - 常量封装
# -*- coding:utf-8 -*- ''' @project: ApiAutoTest @author: Jimmy @file: contants.py @ide: PyCharm Com ...
- PostgreSQL 全文索引
-- 首先要创建自定义的词典,在不使用停用词文件的情况下创建自定义词典,例如: CREATE TEXT SEARCH DICTIONARY english_stem_nostop ( Template ...
- 使mysql的表内容可以输入中文内容
修改数据库的字符集mysql>use mydb mysql>alter database mydb character set utf8;