最短路变短了------------------------------------思维(最短路+套路题)

在这里插入图片描述
在这里插入图片描述
解析:
套路题!!!
用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;
	}
}

发布了572 篇原创文章 · 获赞 14 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/qq_43690454/article/details/105451550