Describe
n个点,m条边数据,n条出租车数据,出租车有一个距离上线ti和一个固定花费值ci,问你从s到e的最小出租车花费是多少,不能到达则输出-1
Solution
建两次图,第一次建造距离图,根据距离图进行n次最短路,确定一个最短路map,然后根据这个最短路地图进行第二次建图,遍历每个点,如果最短距离小于出租车上线则进行建图加边操作,根据第二次建图求最短路,进行输出/判断
Code
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 1e3 + 1e2;
const long long inf = 1e18;
int n,m,s,e;
struct node{
int to,cost,pre;
}edge[maxn*maxn];
int id[maxn],cnt;
int vis[maxn];
ll dis[maxn][maxn];
ll retdis[maxn];
queue<int> q;
void init(){
memset(id,-1,sizeof(id));
cnt = 0;
}
void add(int from,int to,int cost){
edge[cnt].to = to;
edge[cnt].cost = cost;
edge[cnt].pre = id[from];
id[from] = cnt++;
}
void spfa(int s,ll *d){
memset(vis,0,sizeof(vis));
while(q.size())q.pop();
for(int i = 1;i <= n;++i){
d[i] = inf;
}
d[s] = 0;
q.push(s);
vis[s] = 1;
while(q.size()){
int now = q.front();q.pop();vis[now] = 0;
for(int i = id[now];~i;i = edge[i].pre){
int to = edge[i].to;
int cost = edge[i].cost;
if(d[to] > d[now] + cost){
d[to] = d[now] + cost;
if(!vis[to]){
vis[to] = 1;
q.push(to);
}
}
}
}
}
int main()
{
while(~scanf("%d%d%d%d",&n,&m,&s,&e)){
int a,b,v;
init();
for(int i = 1;i <= m;++i){
scanf("%d%d%d",&a,&b,&v);
add(a,b,v);
add(b,a,v);
}
for(int i = 1;i <= n;++i)
spfa(i,dis[i]);
memset(edge,0,sizeof(edge));
init();
int ti,ci;
for(int i = 1;i <= n;++i){
scanf("%d%d",&ti,&ci);
for(int j = 1;j <= n;++j){
if(i == j)continue;
if(dis[i][j] <= ti){
add(i,j,ci);
}
}
}
spfa(s,retdis);
if(retdis[e] == inf){
puts("-1");
}
else{
printf("%lld\n",retdis[e]);
}
}
return 0;
}