Planets CodeForces - 230D

http://codeforces.com/problemset/problem/230/D

在普通最短路的基础上 每个点在一些时间点是无法到达的 看了题解才懂。。

松驰每个点时 看一下该点在当前用来松弛的这个时间点能否到达 能就直接松驰 不能就找一个最近的合法时间 这样对于每个点 相当于来的时间段不同 则边的权值不同 预处理二分即可

#include <bits/stdc++.h>
using namespace std;
const int N=0x3f3f3f3f;

struct node
{
    int v;
    int w;
    int next;
};

vector <int> pre[100010],nxt[100010];
queue <int> que;
node edge[200010];
int first[100010],dis[100010],book[100010];
int n,m,num;

void addedge(int u,int v,int w)
{
    edge[num].v=v;
    edge[num].w=w;
    edge[num].next=first[u];
    first[u]=num++;
}

int gettime(int u,int t)
{
    int l,r,mid;
    l=0,r=pre[u].size()-1;
    while(l<=r)
    {
        mid=(l+r)/2;
        if(pre[u][mid]<t) l=mid+1;
        else if(pre[u][mid]>t) r=mid-1;
        else return nxt[u][mid];
    }
    return t;
}

int spfa()
{
    int i,u,v,w,res;
    memset(dis,0x3f,sizeof(dis));
    que.push(1);
    dis[1]=gettime(1,0);
    book[1]=1;
    while(!que.empty())
    {
        u=que.front();
        que.pop();
        book[u]=0;
        //printf("***%d***\n",u);
        for(i=first[u];i!=-1;i=edge[i].next)
        {
            v=edge[i].v,w=edge[i].w;
            if(v==n) res=dis[u]+w;
            else res=gettime(v,dis[u]+w);
            if(dis[v]>res)
            {
                dis[v]=res;
                if(book[v]==0)
                {
                    que.push(v);
                    book[v]=1;
                }
            }
        }
    }
    return dis[n];
}

int main()
{
    int i,j,u,v,w,k,p,res;
    scanf("%d%d",&n,&m);
    memset(first,-1,sizeof(first));
    num=0;
    for(i=1;i<=m;i++)
    {
        scanf("%d%d%d",&u,&v,&w);
        addedge(u,v,w);
        addedge(v,u,w);
    }
    for(i=1;i<=n;i++)
    {
        scanf("%d",&k);
        while(k--)
        {
            scanf("%d",&w);
            pre[i].push_back(w);
            nxt[i].push_back(0);
        }
        sort(pre[i].begin(),pre[i].end());
        for(j=pre[i].size()-1,p=-1;j>=0;j--)
        {
            if(p==-1||pre[i][j]+1!=pre[i][j+1]) nxt[i][j]=pre[i][j]+1;
            else nxt[i][j]=p;
            p=nxt[i][j];
        }
    }
    res=spfa();
    if(res==N) printf("-1\n");
    else printf("%d\n",res);
    return 0;
}

/*
2 1
1 2 3
0
1 3
*/

猜你喜欢

转载自blog.csdn.net/sunyutian1998/article/details/82453733