CF95C volleyball [最短路+想法]

给出一个图,双向边,边上有权值代表路的距离,然后每个点上有两个值,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;
}


 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值