Codeforces Beta Round #77 (Div. 1 Only), problem: (C) Volleyball dijstra+heap

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


你可能感兴趣的:(Codeforces Beta Round #77 (Div. 1 Only), problem: (C) Volleyball dijstra+heap)