HLG 1066 World Exposition’s Puzzle【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;
}

 

posted @ 2012-06-23 08:10  'wind  阅读(290)  评论(0)    收藏  举报