解析:
套路题!!!
用dij预处理出1到其余点的最短路(用d1[]记录),再处理n到其余点的最短路(用d2[]记录)
设最初的最短路为dn
如果(x,y)这条路,路径反转使得最短路变短了。说明新的最短路一定经过这条边
所以我们只要计算d1[y] + d2[x] + w(x,y) < dn 如果满足输出YES
否输出NO
#include<bits/stdc++.h>
#define x first
#define y second
using namespace std;
typedef long long ll;
const int N=2e5+100000;
typedef pair<ll,ll> PII;
vector<PII> g1[N],g2[N];
ll d1[N],d2[N],w;
int n,m,u,v;
struct node
{
ll u,v,w;
}e[N];
void dij(vector<PII> g[],ll d[],int s)
{
for(int i=1;i<=n;i++) d[i]=1e18;
d[s]=0;
priority_queue<PII,vector<PII>,greater<PII> > q;
q.push({0,s});
while(q.size())
{
auto p=q.top();
q.pop();
int ver=p.y;
for(auto i:g[ver])
{
int j=i.x;
ll w=i.y;
if(d[j]>w+d[ver])
{
d[j]=w+d[ver];
q.push({d[j],j});
}
}
}
}
int main()
{
scanf("%d %d",&n,&m);
for(int i=1;i<=m;i++)
{
scanf("%d %d %lld",&u,&v,&w);
g1[u].push_back({v,w});
g2[v].push_back({u,w});
e[i]={u,v,w};
}
dij(g1,d1,1);dij(g2,d2,n);
int k;
cin>>k;
while(k--)
{
ll x;
cin>>x;
if(d1[e[x].v]+d2[e[x].u]+e[x].w<d1[n])
{
cout<<"YES"<<endl;
}
else cout<<"NO"<<endl;
}
}