最短路变短了【最短路】
题意:
分析:
首先,在原图上以点 11 为起点跑一遍最短路,处理出 dis1[i]dis1[i];
然后,把所有边反向以点 nn 为起点跑一遍最短路,处理出 dis2[i]dis2[i];
当把第 ii 条边反向后,假设该边的为 u→vu→v,边权为 cc。修改之后的图与原图相比,可能替代原来最短路变成新最短路的路径只有可能是 1→v→u→n1→v→u→n。
因此,需要判断该条路径和原最短路的关系。
当 dis1[v]+dis2[u]+c<dis1[n]dis1[v]+dis2[u]+c<dis1[n] 时,表示最短路变短,否则没有。
证明:
对于该式子:
dis1[v]+dis2[u]+cdis1[v]+dis2[u]+c
dis2[u]dis2[u] 为反向图时求的最短路,把边反向时对其值没有影响。cc 的值也不变。但边 u→vu→v 反转后,可能会对 dis1[v]dis1[v] 产生影响,只需要对 dis1[v]dis1[v] 进行讨论。
当 dis1[v]dis1[v] 并没有经过边 u→vu→v 时,dis1[v]dis1[v] 并没有发生改变,可以直接用于判断。
当 dis1[v]dis1[v] 经过了边 u→vu→v 时,那么当该边反向后,dis1[v]′≥dis1[v]dis1[v]′≥dis1[v],如果仍用 dis1[v]dis1[v] 来判断的话,这条新的路径的长度会比原来路径 1→u→v→n1→u→v→n 要多 cc,因此必然不可能,所以用 dis1[v]dis1[v] 仍然可以判断。
代码:
#include <bits/stdc++.h>
#define pb push_back
using namespace std;
typedef long long ll;
typedef pair<ll,int>P;
const ll inf=1e16;
const int N=1e5+5;
struct edge
{
int u,v;
ll w;
}e[N<<1];
vector<P>G[2][N];
priority_queue<P,vector<P>,greater<P> >que;
ll dis[2][N];
void read(int &x)
{
x=0;
int f=1;
char ch=getchar();
while(!isdigit(ch))
{
if(ch=='-')
f=-1;
ch=getchar();
}
while(isdigit(ch))
{
x=(x<<3)+(x<<1)+ch-'0';
ch=getchar();
}
x*=f;
}
void dij(int s,int f,int n)
{
while(!que.empty())
que.pop();
que.push(make_pair(0,s));
for(int i=1;i<=n;i++)
dis[f][i]=inf;
dis[f][s]=0;
while(!que.empty())
{
P now=que.top();
que.pop();
if(dis[f][now.second]<now.first)
continue;
for(int i=0;i<G[f][now.second].size();i++)
{
P tmp=G[f][now.second][i];
if(dis[f][tmp.second]>dis[f][now.second]+tmp.first)
{
dis[f][tmp.second]=dis[f][now.second]+tmp.first;
que.push(make_pair(dis[f][tmp.second],tmp.second));
}
}
}
}
int main()
{
int n,m,u,v,c,q,d;
read(n),read(m);
for(int i=1;i<=m;i++)
{
read(u),read(v),read(c);
G[0][u].pb(make_pair(c,v));
G[1][v].pb(make_pair(c,u));
e[i].u=u;
e[i].v=v;
e[i].w=c;
}
dij(1,0,n);
dij(n,1,n);
read(q);
while(q--)
{
read(d);
if(dis[0][e[d].v]+dis[1][e[d].u]+e[d].w<dis[0][n])
printf("YES\n");
else
printf("NO\n");
}
return 0;
}
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· .NET Core GC计划阶段(plan_phase)底层原理浅谈
· .NET开发智能桌面机器人:用.NET IoT库编写驱动控制两个屏幕
· 用纯.NET开发并制作一个智能桌面机器人:从.NET IoT入门开始
· 一个超经典 WinForm,WPF 卡死问题的终极反思
· ASP.NET Core - 日志记录系统(二)
· 支付宝事故这事儿,凭什么又是程序员背锅?有没有可能是这样的...
· 在线客服系统 QPS 突破 240/秒,连接数突破 4000,日请求数接近1000万次,.NET 多
· C# 开发工具Visual Studio 介绍
· 在 Windows 10 上实现免密码 SSH 登录
· C#中如何使用异步编程