http://acm.hdu.edu.cn/showproblem.php?pid=4396

题意:在至少走k条边的前提下求最短路

思路:在原有最短路模板的基础上多加一维,dis[i][j]表示走到i点经过j条边的最短路,没有别的变化

#include <iostream>
#include <cstdio>
#include <cstring>
#include <queue>
using namespace std ;

const int INF=0xfffffff ;
struct node{
    int s,t,v,nxt ;
}e[1000005] ;

int n,m,k,cnt,head[100005],vis[100005][55],dis[100005][55] ;

void add(int s,int t,int v)
{
    e[cnt].s=s ;
    e[cnt].t=t ;
    e[cnt].v=v ;
    e[cnt].nxt=head[s] ;
    head[s]=cnt++ ;
}

void spfa(int s)
{
    for(int i=0 ;i<=n ;i++)
        for(int j=0 ;j<55 ;j++)
            dis[i][j]=INF ;
    dis[s][0]=0 ;
    memset(vis,0,sizeof(vis)) ;
    vis[s][0]=1 ;
    queue <pair<int,int> > q ;
    q.push(make_pair(s,0)) ;
    while(!q.empty())
    {
        pair<int,int> u=q.front() ;
        q.pop() ;
        vis[u.first][u.second]=0 ;
        int step=u.second+1 ;
        if(step>k)step=k ;
        for(int i=head[u.first] ;i!=-1 ;i=e[i].nxt)
        {
            int tt=e[i].t ;
            if(dis[tt][step]>dis[u.first][u.second]+e[i].v)
            {
                dis[tt][step]=dis[u.first][u.second]+e[i].v ;
                if(!vis[tt][step])
                {
                    vis[tt][step]=1 ;
                    q.push(make_pair(tt,step)) ;
                }
            }
        }
    }
}
int main()
{
    while(~scanf("%d%d",&n,&m))
    {
        cnt=0 ;
        memset(head,-1,sizeof(head)) ;
        while(m--)
        {
            int a,b,c ;
            scanf("%d%d%d",&a,&b,&c) ;
            add(a,b,c) ;
            add(b,a,c) ;
        }
        int s,t ;
        scanf("%d%d%d",&s,&t,&k) ;
        k=k/10+(k%10!=0) ;
        spfa(s) ;
        if(dis[t][k]==INF)puts("-1") ;
        else printf("%d\n",dis[t][k]) ; 
    }
    return 0 ;
}
View Code