问题 P: 最小时间

前言必读!http://blog.csdn.net/hnust_v/article/details/51747743
问题 P: 最小时间

题目描述

       有多个城市组成一个铁路交通网络。任意两个城市之间有直连铁路,或者通过其他城市间接到达。给定某个城市,要求min时间内能到达任意指定的另一城市,求最小min。
输入

每个测试用例由多行组成,第一行是整数n(1 <= n <= 100),表示城市的数目。

其余行表示邻接矩阵A。A(i,j)的值如果是一个整数t,表示城市i与城市j有铁路直连,需要t时间到达另一方。如果A(i,j)的值为x,表明城市i与城市j之间没有直连铁路。很明显有A(i,i) = 0。

由于对称关系和A(i,i) 为 0,输入只给出矩阵的下三角。第一行A(1,1)在输入中省略,第二行只有A(2,1),下一行则是A(3,1) 和A(3,2),依此类推。
输出

输出城市1所对应的min。
样例输入
5
50
30 5
100 20 50
10 x x 10
样例输出
35
提示

这题目调了很久,最后才知道居然是有个数据n后面多空白符!
不过自己看着百度上的伪代码实现了DIJ多少还是有点成就感的。

给出dijkstra算法伪代码:

求最短路径步骤
算法步骤如下:
G={V,E}
1. 初始时令 S={V0},T=V-S={其余顶点},T中顶点对应的距离值
若存在<V0,Vi>,d(V0,Vi)为<V0,Vi>弧上的权值
若不存在<V0,Vi>,d(V0,Vi)为∞
2.T中选取一个与S中顶点有关联边且权值最小的顶点W,加入到S中
3. 对其余T中顶点的距离值进行修改:若加进W作中间顶点,从V0到Vi的距离值缩短,则修改此距离值
重复上述步骤23,直到S中包含所有顶点,即W=Vi为止
//C++实现,其中Handle函数是从字符串内获取信息
#include <bits/stdc++.h>
using namespace std;
#define INF -1
int Point[200][200];//!矩阵
int DIS[200][200];
int V;
char String[100000];
void Handle(int n)//!临接矩阵
{
    for(int i=1;i<=n;i++) Point[i][i]=0;//!对角线
    for(int i=2;i<=n;i++)
    {
        int I=i,J=1;
        gets(String+1);
        int len = strlen(String+1);
        for(int t=1;t<=len;t++)
        {
            if(String[t]=='x')
            {
               Point[J][I] = Point[I][J] = INF;
               J++;
            }
            else if(String[t]==' ') continue;
            else
            {
                int a;
                sscanf(String+t,"%d",&a);
                Point[J][I] = Point[I][J] = a;
                J++;
                for(int step=0;;step++)
                    if(String[t]!=' ') t++;
                    else break;
            }
        }
    }
/*
    for(int i=1;i<=n;i++,puts("\n\n"))
        for(int j=1;j<=n;j++) printf("%5d ",Point[i][j]);
    */
}
int dijkstra(int n,int Begin)
{
    int S[200];
    int T[200],Distance[200];S[1]=Begin;
    int CountS = 1,CountT=0;
    for(int i=1;i<=n;i++)  Distance[i] = Point[Begin][i];
    for(int i=1;i<=n;i++) if(i!=Begin) T[++CountT]=i;
    int J;
    while(CountS!=n)
    {
        /*
printf("S={ ");for(int i=1;i<=CountS;i++) printf("%d ",S[i]);printf("}\n");
printf("T={ ");for(int i=1;i<=CountT;i++) printf("%d ",T[i]);printf("}\n\n");
*/
//for(int i=1;i<=CountT;i++) if(T[i]) printf("Distance[%d]==%d\n",T[i],Distance[T[i]]);
        int MIN_D=INT_MAX,Del;
        for(int i=1;i<=CountS;i++)
            for(int j=1;j<=CountT;j++)
                if(T[j] && Distance[T[j]]!=INF && MIN_D>=Distance[T[j]])
                        {MIN_D = Distance[T[j]];J = T[j];Del=j;}

//printf("选取点%d\n",J);
        for(int i=1;i<=CountT;i++)
        {
           // printf("T[i]==%d J==%d Point[J][T[i]]=%d Distance[J]+Point[J][T[i]]=%d\n",T[i],J,Point[J][T[i]],Distance[J]+Point[J][T[i]]);
            if(Distance[T[i]]==INF&&(Point[J][T[i]]!=INF)) Distance[T[i]] = Distance[J]+Point[J][T[i]];
            else if(T[i]&&(Point[J][T[i]]!=INF)&&(Distance[T[i]]>Distance[J]+Point[J][T[i]]))
                Distance[T[i]] = Distance[J]+Point[J][T[i]];
        }
        S[++CountS] = J;
        T[Del]=0;
    }
/*
printf("S={ ");for(int i=1;i<=CountS;i++) printf("%d ",S[i]);printf("}\n");
printf("T={ ");for(int i=1;i<=CountT;i++) printf("%d ",T[i]);printf("}\n");
*/
    return Distance[J];
}
int main()
{
   // freopen("F:\\test.txt","r",stdin);
    int n;char T[50];
    while(~scanf("%d",&n))
    {
        gets(T);
        Handle(n);
        V=n;
        printf("%d\n",dijkstra(n,1));
    }
}
  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值