题目链接  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. web开发框架tornado

    在server.py文件中 import tornado.web import tornado.ioloop import tornado.httpserver import config from ...

  2. python列表中的深浅copy

    列表中的赋值和平常的赋值是不一样的,看下面的代码: In [1]: a = 1 In [2]: b = a In [3]: a Out[3]: 1 In [4]: b Out[4]: 1 In [5] ...

  3. Git命令大总结(纯手办)

    Git完整命令手册地址:http://git-scm.com/docs PDF版命令手册地址:github-git-cheat-sheet.pdf 1.git config -l查看全局用户信息配置 ...

  4. 通过Proxool配置访问数据库的要点

    proxool 配置的时候有Proxool.properties 或者 Proxool.xml 两种方式初始化. 我的配置环境是 myEclipse10+tomcat6.0 + mysql5.0 . ...

  5. SPOJ 1825 Free tour II 树分治

    题意: 给出一颗边带权的数,树上的点有黑色和白色.求一条长度最大且黑色节点不超过k个的最长路径,输出最长的长度. 分析: 说一下题目的坑点: 定义递归函数的前面要加inline,否则会RE.不知道这是 ...

  6. UVa 1407 树形背包 Caves

    这道题可以和POJ 2486 树形背包DP Apple Tree比较着来做. 参考题解 #include <iostream> #include <cstdio> #inclu ...

  7. 你应该知道的.net平台下socket异步通讯(代码实例)

    1,首先添加两个windows窗体项目,一个作为服务端server,一个作为客户端Client 2,然后添加服务端代码,添加命名空间,界面上添加TextBox控件 using System.Net; ...

  8. loadrunner参数化数据分配方法

    数据分配方法: 在“Select next row“列表中选择一个数据分配方法,以指示在Vuser脚本执行期间如何从参数文件中取得数据.选项包括”Sequential“.“Random”.“Uniqu ...

  9. matlab 初级画图

    matlab 初级画图 1.plot() plot(x,y)   plots each vector pairs (x,y) 画图函数画出每个点   每组变量 plot (y)   plots eac ...

  10. [svn学习篇]svn使用教程

    http://www.cnblogs.com/longshiyVip/p/4905901.html http://blog.csdn.net/dily3825002/article/details/6 ...