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

来源:互联网 发布:淘宝图片水印在线制作 编辑:程序博客网 时间:2024/06/04 18:59

做法:一开始WA,因为没想到dijstra的复杂度可以降到nlogn,紧接着用了floyed,就是TLE不断了。发现这个真是神算法。

首先用dijstra求出每个点之间的最短路,然后重新构图,再一次dijstra即可

#include<queue>#include<cstdio>#include<vector>#include<cstring>#include<algorithm>#define eps 1e15#define LL long longusing 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;}


原创粉丝点击