问题 P: 最小时间

来源:互联网 发布:支持xen的linux内核 编辑:程序博客网 时间:2024/06/06 18:34

前言必读!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。样例输入55030 5100 20 5010 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 -1int 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));    }}
0 0