题目链接  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预处理 + 线段树维护最小值)的更多相关文章

  1. Wannafly挑战赛2_D Delete(拓扑序+最短路+线段树)

    Wannafly挑战赛2_D Delete Problem : 给定一张n个点,m条边的带权有向无环图,同时给定起点S和终点T,一共有q个询问,每次询问删掉某个点和所有与它相连的边之后S到T的最短路, ...

  2. 【拓扑排序】【线段树】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 ...

  3. bzoj4383 [POI2015]Pustynia 拓扑排序+差分约束+线段树优化建图

    题目传送门 https://lydsy.com/JudgeOnline/problem.php?id=4383 题解 暴力的做法显然是把所有的条件拆分以后暴力建一条有向边表示小于关系. 因为不存在零环 ...

  4. Wannafly挑战赛10 D 小H的询问(线段树)

    题目链接  Problem D 这个题类似 SPOJ GSS3 做过那个题之后其实就可以秒掉这题了. 考虑当前线段树维护的结点 在那道题的基础上,这个题要多维护几个东西,大概就是左端点的奇偶性,右端点 ...

  5. [luogu3573 POI2014] RAJ-Rally (拓扑排序 权值线段树)

    传送门 Solution 在DAG中我们可以\(O(n)\)预处理\(Ds(u)\)表示从u表示以s为起点的最长路\(Dt(u)\)表示以u为终点的最长路,那么经过\((u,v)\)的最长路即为\(D ...

  6. [BZOJ4552][TJOI2016&&HEOI2016]排序(二分答案+线段树/线段树分裂与合并)

    解法一:二分答案+线段树 首先我们知道,对于一个01序列排序,用线段树维护的话可以做到单次排序复杂度仅为log级别. 这道题只有一个询问,所以离线没有意义,而一个询问让我们很自然的想到二分答案.先二分 ...

  7. 【拓扑 字符串还原 + 线段树维护】奇洛金卡达(father)

    奇洛金卡达(father) Description 阿良良木历将要迎来人生(不,是吸血鬼生涯)的第三次战斗——与身为人类的奇洛金卡达在直江津高中的操场solo,以取回Heartunderblade 的 ...

  8. 2018.08.01 BZOJ4552: [Tjoi2016&Heoi2016]排序(二分+线段树)

    传送门 线段树简单题. 二分答案+线段树排序. 实际上就是二分答案mid" role="presentation" style="position: relat ...

  9. 【BZOJ4552】【HEOI2016】排序 [二分答案][线段树]

    排序 Time Limit: 60 Sec  Memory Limit: 256 MB[Submit][Status][Discuss] Description 在2016年,佳媛姐姐喜欢上了数字序列 ...

随机推荐

  1. thinkcmf5更新模板代码分析,解决模板配置json出错导致数据库保存的配置项内容丢失问题

    private function updateThemeFiles($theme, $suffix = 'html') { $dir = 'themes/' . $theme; $themeDir = ...

  2. ccf 201803-1 跳一跳(Python实现)

    一.原题 问题描述 试题编号: 201803-1 试题名称: 跳一跳 时间限制: 1.0s 内存限制: 256.0MB 问题描述: 问题描述 近来,跳一跳这款小游戏风靡全国,受到不少玩家的喜爱. 简化 ...

  3. hdu 5441

    Travel Time Limit: 1500/1000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others)Total Su ...

  4. 配置hibernate常见问题

    连接MySql时出现:The server time zone value '�й���׼ʱ��' is unrecognized or represents more than one time z ...

  5. Leetcode23--->Merge K sorted Lists(合并k个排序的单链表)

    题目: 合并k个排序将k个已排序的链表合并为一个排好序的链表,并分析其时间复杂度 . 解题思路: 类似于归并排序的思想,lists中存放的是多个单链表,将lists的头和尾两个链表合并,放在头,头向后 ...

  6. GBDT 与 XGBoost

    GBDT & XGBoost ### 回归树 单棵回归树可以表示成如下的数学形式 \[ f(x) = \sum_j^Tw_j\mathbf{I}(x\in R_j) \] 其中\(T\)为叶节 ...

  7. [git 学习篇] --创建git创库

    http://www.liaoxuefeng.com/wiki/0013739516305929606dd18361248578c67b8067c8c017b000/0013743256916071d ...

  8. [错误处理]UnicodeDecodeError: 'ascii' codec can't decode byte 0xe5 in position 0: ordinal not in range(128)

    Stackoverflow 回答: 将byte类型转化:byte_string.decode('utf-8') Jinja2 is using Unicode internally which mea ...

  9. centos7 install google-chrome

    important: Google Chrome support for all 32-bit Linux distributions is deprecated from March, 2016. ...

  10. 利用hibernate与struts框架制作简单注册界面

    一:配置hibernate 1.导包 hibernate包和jdbc连接mysql数据库的包 2.实用工具生成hibernate配置文件和映射文件 3.做好hibernateUtil生成session ...