给出一个图,双向边,边上有权值代表路的距离,然后每个点上有两个值,t,c,t代表能从这个点最远沿边走t,且不能在半路下来,花费是c
现在告诉你起点终点,问最少的花费
点个数1000,边个数1000,边权1e9
建新图
对每个点求一次最短路,然后,连边,u:这个点,v:从这个点到其他点距离小于t的点,w:这个点的花费c,然后把新图以起始点为原点跑一边最短路,输出dis[终点]
再次说明注意坑:
1.爆int,用long long
2.不可达时输出-1
3.用long long时候,最大值不再是INT_MAX
#include <cstdio>
#include <cstring>
#include <cmath>
#include <iostream>
#include <queue>
#include <vector>
#include <algorithm>
#include <climits>
using namespace std;
#define pb push_back
const long long INF=(1LL<<62)+(1LL<<61);
long long n,m;
long long st,ed;
struct EDGE{long long v,w;};
struct POINT{long long t,c;}p[1111];
vector<EDGE> G[1111];
vector<EDGE> G2[1111];
typedef pair<long long,long long> P;
long long V;
long long d[1111];
void dijkstra(long long s,vector<EDGE> G[]){
priority_queue<P,vector<P>,greater<P> > que;
fill(d+1,d+V+1,INF);
d[s]=0;
que.push(P(0,s));
while(!que.empty()){
P p=que.top();que.pop();
long long v=p.second;
if(d[v]<p.first) continue;
for(long long i=0;i<G[v].size();i++){
EDGE e=G[v][i];
if(d[e.v]>d[v]+e.w){
d[e.v]=d[v]+e.w;
que.push(P(d[e.v],e.v));
}
}
}
}
int main(){
#ifndef ONLINE_JUDGE
freopen("G:/in.txt","r",stdin);
//freopen("G:/myout.txt","w",stdout);
#endif
scanf("%I64d%I64d%I64d%I64d",&n,&m,&st,&ed);
V=n;
for(long long i=1;i<=m;i++){
long long u,v,w;
scanf("%I64d%I64d%I64d",&u,&v,&w);
G[u].pb((EDGE){v,w});
G[v].pb((EDGE){u,w});
}
for(long long i=1;i<=n;i++){
long long t,c;
scanf("%I64d%I64d",&t,&c);
p[i]=(POINT){t,c};
}
for(long long i=1;i<=n;i++){
dijkstra(i,G);
for(long long j=1;j<=n;j++){
if(d[j]<=p[i].t){
G2[i].pb((EDGE){j,p[i].c});
}
}
}
dijkstra(st,G2);
if(d[ed]==INF){puts("-1");return 0;}
printf("%I64d\n",d[ed]);
return 0;
}