做法:一开始WA,因为没想到dijstra的复杂度可以降到nlogn,紧接着用了floyed,就是TLE不断了。发现这个真是神算法。
首先用dijstra求出每个点之间的最短路,然后重新构图,再一次dijstra即可
#include<queue> #include<cstdio> #include<vector> #include<cstring> #include<algorithm> #define eps 1e15 #define LL long long using namespace std; const int LMT=2004; struct line { int u,v,next,len; }e[2000000]; LL dis[LMT]; int next[LMT],all,n,m,s,vis[LMT]; LL c[LMT],timid[LMT]; void insert(int u,int v,int len) { e[all].u=u; e[all].v=v; e[all].len=len; e[all].next=next[u]; next[u]=all++; } struct cmp { bool operator()(const int a,const int b) { return dis[a]>dis[b]; } }; void dij(int s) { priority_queue<int,vector<int>,cmp>q; int u; for(int i=0;i<LMT;i++)dis[i]=eps; memset(vis,0,sizeof(vis)); dis[s]=0; q.push(s); while(!q.empty()) { u=q.top(); q.pop(); if(vis[u])continue; vis[u]=1; for(int x=next[u];x!=-1;x=e[x].next) if(0==vis[e[x].v]&&dis[e[x].v]>dis[e[x].u]+e[x].len) { dis[e[x].v]=dis[e[x].u]+e[x].len; q.push(e[x].v); } } } int main(void) { int u,v,len,x,y; memset(next,-1,sizeof(next)); scanf("%d%d%d%d",&n,&m,&x,&y); while(m--) { scanf("%d%d%d",&u,&v,&len); insert(u,v,len); insert(v,u,len); } for(int i=1;i<=n;i++)scanf("%I64d%I64d",&timid[i],&c[i]); for(int i=1;i<=n;i++) { dij(i); for(int j=1;j<=n;j++) if(dis[j]<=timid[i]) insert(i+n,j+n,c[i]); } dij(x+n); if(dis[y+n]==eps)printf("-1\n"); else printf("%I64d\n",dis[y+n]); return 0; }