前言必读!http://blog.youkuaiyun.com/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的距离值缩短,则修改此距离值
重复上述步骤2、3,直到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));
}
}