HDU 4396 More lumber is required

题意: 给出一个地图,要求找出至少经过K条边的最短路,可以走重边。

分析:二维最短路,用dis[i][j] 记录 在i 点进过j 条路的最短路

        找到dis[i][k]的最小值。

SPFA:

#include<stdio.h>
#include<string.h>
#include<queue>
#define INF 0x1f1f1f1f
using namespace std;
#define maxn 5005
struct node
{
    int to,next,w;
}e[200005];
int tot;
int head[maxn];
void add(int s,int u,int wi)
{
    e[tot].to=u;
    e[tot].w=wi;
    e[tot].next=head[s];
    head[s]=tot++;
}
struct dd
{
    int xu,dis,ti;
}q[300000],tt,in;
int n;
int d[5005][505];
int v[5005][505];
int k;
int spfa(int st,int en)
{
    int i,front,rear,u,c,tmp;
    memset(d,INF,sizeof(d));
    memset(v,0,sizeof(v));
    v[st][0]=1;
    d[st][0]=0;
    in.dis=0;
    in.ti=0;
    in.xu=st;
    front=rear=0;
    q[rear++]=in;
    while(front<rear)
    {
        tt=q[front++];
        v[tt.xu][tt.ti]=0;
        for(i=head[tt.xu];i;i=e[i].next)
        {
            in.xu=e[i].to;
            in.dis=d[tt.xu][tt.ti]+e[i].w;
            if(tt.ti+1>k)
                in.ti=k;
            else in.ti=tt.ti+1;
            if(d[in.xu][in.ti]>in.dis)
            {
                d[in.xu][in.ti]=in.dis;
                if(!v[in.xu][in.ti])
                {
                    v[in.xu][in.ti]=1;
                    q[rear++]=in;
                }
            }
        }
    }
    if(d[en][k]==INF)
        return -1;
    else return d[en][k];
}
int main()
{
    int s,t,m,a,b,c,res;
    while(scanf("%d%d",&n,&m)!=EOF)
    {
        tot=1;
        memset(head,0,sizeof(head));
        while(m--)
        {
            scanf("%d%d%d",&a,&b,&c);
            add(a,b,c);
            add(b,a,c);
        }
        scanf("%d%d%d",&s,&t,&k);
        k=(k-1)/10+1;
        printf("%d\n",spfa(s,t));
    }
    return 0;
}

 

posted @ 2012-08-26 11:13  'wind  阅读(215)  评论(0编辑  收藏  举报