最短路变短了 (思维+反向djstrea)
题解:设有一条边x->y,数组dis1[i]表示从1到i的最短距离,dis2[i]表示从n到i的最短距离。
1 如果说将x->y反向之前没有经过x->y,但是反向后我经过了x,y说明找到了一个更优的路径,那么反向后的答案就是dis1[y]+dis2[x]+(x,y),如果说反向后我没有经过
x->y,那也就是说x->y正向反向对dis[n]的结果没有影响喽。
2 如果说反向之前我经过了x->y,如果反向后没有经过x->y,那么此时的最短路也一定是大于等于dis1[n]的,因为会有一条新的路径长度处于dis1[n]和dis1[y]+dis2[x]+(x,y)之间。如果反向后经过了x->y,那么反向后的答案就是dis1[y]+dis2[x]+(x,y)。
综上所述,我们只需要判断dis1[y]+dis2[x]+(x,y)和dis1[n]的关系就行了。(看起来有点绕,仔细品品还是很有意思的)
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll N=2e5+;
const ll INF=1e18+; struct stu{
ll a,b;
bool friend operator<(const stu &x,const stu &y){
return x.b>y.b;
}
};
vector<stu>ve1[N];
vector<stu>ve2[N];
ll l[N],r[N],w[N];
ll n,m;
bool mark[N];
ll dis1[N],dis2[N];
void add1(ll x,ll y,ll weight){
ve1[x].push_back({y,weight});
}
void add2(ll x,ll y,ll weight){
ve2[x].push_back({y,weight});
}
void inll(){
for(ll i=;i<=n;i++){
dis1[i]=dis2[i]=INF;
}
}
void djstrea1(ll s){
priority_queue<stu>que;
dis1[s]=;
que.push({s,});
while(que.size()){
stu xx=que.top();
que.pop();
if(mark[xx.a]==) continue ;
mark[xx.a]=;
for(ll i=;i<ve1[xx.a].size();i++){
ll dx=ve1[xx.a][i].a;
ll dy=ve1[xx.a][i].b;
if(mark[dx]==&&dis1[dx]>dis1[xx.a]+dy){
dis1[dx]=dis1[xx.a]+dy;
que.push({dx,dis1[dx]});
}
}
}
}
void djstrea2(ll s){
priority_queue<stu>que;
dis2[s]=;
que.push({s,});
while(que.size()){
stu xx=que.top();
que.pop();
if(mark[xx.a]==) continue ;
mark[xx.a]=;
for(ll i=;i<ve2[xx.a].size();i++){
ll dx=ve2[xx.a][i].a;
ll dy=ve2[xx.a][i].b;
if(mark[dx]==&&dis2[dx]>dis2[xx.a]+dy){
dis2[dx]=dis2[xx.a]+dy;
que.push({dx,dis2[dx]});
}
}
}
}
int main(){
cin>>n>>m;
inll();
for(ll i=;i<=m;i++){
ll x,y,z;
cin>>x>>y>>z;
l[i]=x;r[i]=y;w[i]=z;
add1(x,y,z);
add2(y,x,z);
}
djstrea1();
memset(mark,,sizeof mark);
djstrea2(n);
ll t;
cin>>t;
while(t--){
ll i;cin>>i;
cout<<(dis1[n]>dis1[r[i]]+dis2[l[i]]+w[i]? "YES":"NO")<<endl;
}
return ;
}
最短路变短了 (思维+反向djstrea)的更多相关文章
- luogu 4366 [Code+#4]最短路 Dijkstra + 位运算 + 思维
这个题思路十分巧妙,感觉很多题都有类似的套路. 我们发现异或操作其实就是将一个数的二进制的若干个 $0$ 变成 $1$,或者一些 $1$ 变成 $0$. 而每次按照某种顺序一位一位地异或也可以起到同时 ...
- mysql变成类型字段varchar值更新变长或变短底层文件存储原理
为了搞清楚MySQL对于可变长度字段值修改时,如何高效操作数据文件的机制.之前一直模糊不清,网上也搜不到现成的答案.经过多方资料搜集整理.写出此文供大家一起参阅.由于涉及众多非常底层的知识,我假设读者 ...
- Ubuntu终端里面显示路径名称太长,怎么设置变短【转】
转自:http://blog.csdn.net/id19870510/article/details/8276914 $: sudo vi ~/.bashrc 这个文件记录了用户终端配置 找到 if ...
- ie7 动态改变select option时,宽度自动变短解决方法
<html> <head> <title>JQuery</title> <meta http-equiv="pragma" c ...
- SP338ROADS题解--最短路变式
题目链接 https://www.luogu.org/problemnew/show/SP338 分析 联想到不久前做过的一道题\(Full\) \(Tank\),感觉可以用优先队列做,于是写了\(d ...
- 洛谷4366——最短路(dijkstra,思维,异或)
题目大意 给定一个n个点,m条边的图,每条边有边权,而每个点\(i\)也可以直接到达\(j\),代价是\(i\ xor\ j\),给定一个S和T,求S到T的最小代价 其中\(n\le100000,m\ ...
- floyd最短路
floyd可以在O(n^3)的时间复杂度,O(n^2)的空间复杂度下求解正权图中任意两点间的最短路长度. 本质是动态规划. 定义f[k][i][j]表示从i出发,途中只允许经过编号小于等于k的点时的最 ...
- 「bzoj1003」「ZJOI2006」物流运输 最短路+区间dp
「bzoj1003」「ZJOI2006」物流运输---------------------------------------------------------------------------- ...
- [最短路,floyd] Codeforces 1204C Anna, Svyatoslav and Maps
题目:http://codeforces.com/contest/1204/problem/C C. Anna, Svyatoslav and Maps time limit per test 2 s ...
随机推荐
- git的cd命令
这个命令是进入某个文件夹的命令.进入文件夹后可以对文件夹中的文件进行一系列操作.
- HDU - 1005 Number Sequence 矩阵快速幂
HDU - 1005 Number Sequence Problem Description A number sequence is defined as follows:f(1) = 1, f(2 ...
- 斯坦福经典AI课程CS 221官方笔记来了!机器学习模型、贝叶斯网络等重点速查...
[导读]斯坦福大学的人工智能课程"CS 221"至今仍然是人工智能学习课程的经典之一.为了方便广大不能亲临现场听讲的同学,课程官方推出了课程笔记CheatSheet,涵盖4大类模型 ...
- Hive学习笔记六
目录 查询 一.基本查询 1.全表和特定列查询 2.列别名 3.算术运算符 4.常用函数 5.Limit语句 二.Where语句 1.比较运算符(Between/In/ Is Null) 2.Like ...
- mongodb的更新语句
MongoDB 使用 update() 和 save() 方法来更新集合中的文档: update()方法: update() 方法用于更新已存在的文档.语法格式如下: db.collection.up ...
- Netty耗时的业务逻辑应该写在哪儿,有什么注意事项?
更多技术分享可关注我 前言 Netty以高性能著称,但是在实际使用中,不可避免会遇到耗时的业务逻辑,那么这些耗时操作应该写在哪儿呢,有什么注意的坑吗?本篇文章将一一总结. Netty线程调度模型回顾 ...
- Python库的安装方式
Python库的安装方式 1.Python库的自定义安装——找到相应网站,下载安装 示例:pywin32库安装 .exe,直接双击,自动识别安装目录 安装就可以了. 载入成功 2.Python库的工具 ...
- Mac LaTex中文环境搭建
为了在博客上写公式,折腾了一晚上Mac上的LaTex的环境搭建,本文对步骤进行记录. 系统:Mac OSX 10.10.5 软件准备 1) MacTex 2015 Distribution (Tex的 ...
- linux中的文本处理命令
一.wc :统计文本的行数.字符数. -l:只显示行数 -d:只显示单词数 -c:只显示字符数 二.tr:转换字符或者删除字符 -d:删除字符 三.cut -d:指定分隔符 -f:指定要显示的字段 例 ...
- E - E CodeForces - 1100E(拓扑排序 + 二分)
E - E CodeForces - 1100E 一个n个节点的有向图,节点标号从1到n,存在m条单向边.每条单向边有一个权值,代表翻转其方向所需的代价.求使图变成无环图,其中翻转的最大边权值最小的方 ...