【JZOJ 4489】【GDOI 2016 Day2】第一题 SigemaGO

来源:互联网 发布:淘宝买情趣用品 编辑:程序博客网 时间:2024/06/07 01:41

Description

这里写图片描述
这里写图片描述

Analysis

这题在GDOI上想到了,可是只有20,so sad
对于那个插近道,只需要做lim次最短路即可。把图分层,插近道相当于从上一层的图走到这一层的图。
当然,这一层本身的最短路也要跑的。
SP(b)FA的时间复杂度O(limn),dijkstra的是O(limnlog2n)

Code

#include<cstdio>#include<queue>#include<cstring>#include<algorithm>#define fo(i,a,b) for(int i=a;i<=b;i++)#define efo(i,v) for(int i=last[v];i;i=next[i])using namespace std;const int N=10010,M=50010,INF=2139062143;int n,m,l,tot,to[M],wei[M],next[M],last[N],dis[6][N];bool bz[N];queue<int> q;struct edge{    int x,y,z;}b[M];bool cmp(edge a,edge b){return a.x<b.x;}void link(int u,int v,int w){    to[++tot]=v,wei[tot]=w,next[tot]=last[u],last[u]=tot;}void spfa(int k){    bz[1]=1;    memset(dis[k],127,sizeof(dis[k]));    dis[k][1]=0;    q.push(1);    while(!q.empty())    {        int x=q.front();q.pop();        bz[x]=0;        efo(i,x)        {            int y=to[i];            if(dis[k][x]+wei[i]<dis[k][y])            {                dis[k][y]=dis[k][x]+wei[i];                if(!bz[y])                {                    bz[y]=1;                    q.push(y);                }            }            if(k>0)            efo(j,y)            {                int z=to[j];                if(dis[k-1][x]+l<dis[k][z])                {                    dis[k][z]=dis[k-1][x]+l;                    if(!bz[z])                    {                        bz[z]=1;                        q.push(z);                    }                }            }        }    }}int main(){    freopen("sigemago.in","r",stdin);    freopen("sigemago.out","w",stdout);    int lim,u,v,w;    scanf("%d %d %d %d",&n,&m,&l,&lim);    fo(i,1,m)    {        scanf("%d %d %d",&u,&v,&w);        link(u,v,w);    }    fo(i,0,lim) spfa(i);    printf("%d\n",dis[lim][n]==INF?-1:dis[lim][n]);    fclose(stdin);fclose(stdout);    return 0;}
0 0
原创粉丝点击