题目链接: https://vjudge.net/contest/280753#problem/G
题意: 给你一个无向图,每条边所带的权值为两点之间的距离,每个点都有一辆出租车,每个出租车都有能走最远的距离与费用,要求出租车不能在半路上停车,问从x点到y点坐出租车的最小费用
思路: 首先我们可以用dijkstra求出每个点到其他点的最短路,然后进行重新建图,若是该点到其他点的最小距离大于出租车最大行驶长度,则连接两点,则该条边的权值为出租车的费用,则问题转化为另一个最短路问题,对新图重新dijkstra求一下最短路
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<long long,int>pr;
const ll INF=1e18;
int n,m,x,y,cnt1,cnt2;
int a,b,c;
ll d[1005][1005],D[1005];
int head1[1005],head2[1005];
struct node
{
int v,next;
ll len;
}edge1[2005],edge2[1000005];
void add(int u,int v,int w)
{
edge1[cnt1].v=v;
edge1[cnt1].next=head1[u];
edge1[cnt1].len=w;
head1[u]=cnt1++;
}
void Add(int u,int v,int w)
{
edge2[cnt2].v=v;
edge2[cnt2].len=w;
edge2[cnt2].next=head2[u];
head2[u]=cnt2++;
}
void dijstra(int k)
{
for(int i=1;i<=n;i++)
{
d[k][i]=INF;
}
d[k][k]=0;
priority_queue<pair<ll, int>>que;
que.push(make_pair(0,k));
while(que.size())
{
pr t;
t=que.top();
que.pop();
ll a=-t.first;
int b=t.second;
for(int i=head1[b];i!=-1;i=edge1[i].next)
{
int v=edge1[i].v;
ll lenth=a+edge1[i].len;
if(d[k][v]>lenth){
d[k][v]=lenth;
que.push(make_pair(-lenth,v));
}
}
}
}
void Dijstra(int k)
{
for(int i=1;i<=n;i++)
{
D[i]=INF;
}
D[k]=0;
priority_queue<pair<ll ,int >>que;
que.push(make_pair(0,k));
while(que.size())
{
pr t;
t=que.top();
que.pop();
ll a=-t.first;
int b=t.second;
for(int i=head2[b];i!=-1;i=edge2[i].next)
{
int v=edge2[i].v;
ll lenth=a+edge2[i].len;
if(D[v]>lenth)
{
D[v]=lenth;
que.push(make_pair(-lenth,v));
}
}
}
}
int main()
{
cin>>n>>m;
cin>>x>>y;
memset(head1,-1,sizeof head1);
memset(head2,-1,sizeof head2);
for(int i=1;i<=m;i++)
{
cin>>a>>b>>c;
add(a,b,c);
add(b,a,c);
}
for(int i=1;i<=n;i++)
{
dijstra(i);
}
for(int i=1;i<=n;i++)
{
cin>>a>>b;
for(int j=1;j<=n;j++)
{
if(d[i][j]<=a&&i!=j)
{
Add(i,j,b);
}
}
}
Dijstra(x);
if(D[y]==INF)
cout<<"-1"<<endl;
else
cout<<D[y]<<endl;
return 0;
}