HLG 1066 World Exposition’s Puzzle【dijkstra】

本文介绍了一种基于Dijkstra算法的变种实现方法,旨在解决寻找起点到终点的最短路径问题,同时确保路径中边的数量为给定数值的倍数。通过二维最短路径的构建与调整,该方法能够有效地找到满足条件的最短路径。

题意: 给出一个地图,起点 s,终点 t,和一个数 x,求出s 到 t 的最短路,且经过的路的条数是 x 的倍数。 

分析: 可以看成是二维的最短路,在 原dijkstra的基础上修改,从一个点到另一个点走的边数如果是 d,

          那么从这个点到另一个点走的边数为 d+1, 只要对 X 取模,便能求出从 s 到 t 经过 x 的倍

         数边的最短路径。

 

#include<stdio.h>
#include<string.h>
const long long INF=9999999999;
long long g[102][102];
long long d[102][11];
int v[102][11];
int main()
{
  //  freopen("D:ce2.txt","r",stdin);
    int t,T,n,m,i,j,k,x,p,q,flag;
    int s,u,next,cur;
    long long tmp,w;
    scanf("%d",&T);
    while(T--)
    {
        scanf("%d%d",&n,&m);
        for(i=0;i<n;i++)
        {
            for(j=0;j<11;j++)
             d[i][j]=INF;
            for(j=0;j<n;j++)
              g[i][j]=INF;
        }
        memset(v,0,sizeof(v));
        while(m--)
        {
            scanf("%d%d%lld",&p,&q,&w);
            if(w<g[p][q])
                g[p][q]=w;
        }
        scanf("%d%d%d",&s,&t,&x);
        flag=0;
        d[s][0]=0;
        while(1)
        {
            tmp=INF;
            u=-1;
            for(j=0;j<n;j++)
                for(k=0;k<x;k++)       
                    if(!v[j][k]&&d[j][k]<tmp) // 当前的路径数是k,由当前点得到的新的边加上
                    {                         // 之前的边数 就是 cur+1 
                        tmp=d[j][k];          
                        u=j;
                        cur=k;
                        next=(cur+1)%x;       
                    }                        

            if(u==-1)
                break;
            v[u][cur]=1;
            if(v[t][0])
                break;
            for(j=0;j<n;j++)
                if(!v[j][next]&&d[u][cur]+g[u][j]<d[j][next])  // 下一个点由于是由当前经过 cur 条边得到的
                    d[j][next]=d[u][cur]+g[u][j];              // 所以松弛之后 下一个点经过的 边数就是 next = cur+1
        }
        if(d[t][0]!=INF)
            printf("%lld\n",d[t][0]);
        else printf("No Answer!\n");
    }
    return 0;
}

 

转载于:https://www.cnblogs.com/dream-wind/archive/2012/06/23/2559149.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值