做法:一开始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;
}