现在的位置: 首页 > 综合 > 正文

hdu 4396 More lumber is required (二维SPFA)

2018年02月18日 ⁄ 综合 ⁄ 共 1325字 ⁄ 字号 评论关闭

题目链接:   hdu 4396

题目大意:   给出带权值的无向边,可能会有自环

                  给出起点和终点,求至少经过K条边的最短路径

解题思路:   当k不能被10整除时,K=k%10+1,否则K=k%10;

                  二维SPFA,Dp[ a ][ b ]表示经过b条边到达a点的最短路径

                  剪枝的地方是把b>K的看成b=K,因为b>=K的都是满足题意的答案

                  把b>K并入b=K,省去无用的搜素,降低时间复杂度

代码:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX 5010
#define INF 0x3f3f3f3f
int Dp[MAX][505],pre[MAX],Index,visit[MAX][505];
struct snode{
    int to,w,next;
}Edge[210000];
struct node{
    int v,len;
}listb[2000000],v1,v2;

void Add_edge(int a,int b,int c)
{
    Edge[Index].to=b; Edge[Index].w=c;
    Edge[Index].next=pre[a];
    pre[a]=Index++;
}

int SPFA(int a,int b,int c)
{
    int s,e,i,vv,vlen;
    memset(visit,0,sizeof(visit));
    s=e=0;
    Dp[a][0]=0;
    v1.len=0,v1.v=a;
    listb[s++]=v1;
    while(s!=e)
    {
        v1=listb[e++];
        visit[v1.v][v1.len]=0;
        for(i=pre[v1.v];i!=-1;i=Edge[i].next)
        {
            vlen=v1.len+1;
            if(vlen>=c)    //把 len>K的看成K
                vlen=c;
            vv=Edge[i].to;
            if(Dp[vv][vlen]>Dp[v1.v][v1.len]+Edge[i].w)
            {
                Dp[vv][vlen]=Dp[v1.v][v1.len]+Edge[i].w;  //更新
                if(!visit[vv][vlen])  //防止重复人队列
                {
                    v2.v=vv,v2.len=vlen;
                    visit[vv][vlen]=1;
                    listb[s++]=v2;
                }
            }
        }
    }
    return Dp[b][c];
}

int main()
{
    int i,j,n,m,a,b,c,t;
    while(scanf("%d%d",&n,&m)!=EOF)
    {
        Index=0;
        memset(pre,-1,sizeof(pre));
        memset(Dp,INF,sizeof(Dp));
        for(i=1;i<=m;i++)
        {
            scanf("%d%d%d",&a,&b,&c);
            Add_edge(a,b,c);
            Add_edge(b,a,c);
        }
        scanf("%d%d%d",&a,&b,&c);
        t=c;
        c/=10;
        if(t%10!=0)  //至少为c分,既>=c
            c++;
        t=SPFA(a,b,c);
        if(t==INF)
            printf("-1\n");
        else
            printf("%d\n",t);
    }
    return 0;
}

抱歉!评论已关闭.