详解
在带权有向图G中,给定一个源点v,求从v到G中的其余各顶点的最短路径问题,叫做单源点的最短路径问题。
输入
输入的第一行包含2个正整数n和s,表示图中共有n个顶点,且源点为s。其中n不超过50,s小于n。
以后的n行中每行有n个用空格隔开的整数。对于第i行的第j个整数,如果大于0,则表示第i个顶点有指向第j个顶点的有向边,且权值为对应的整数值;如果这个整数为0,则表示没有i指向j的有向边。当i和j相等的时候,保证对应的整数为0。
输出
只有一行,共有n-1个整数,表示源点至其它每一个顶点的最短路径长度。如果不存在从源点至相应顶点的路径,输出-1。
请注意行尾输出换行。
样例输入
4 1
0 3 0 1
0 0 4 0
2 0 0 0
0 0 1 0
样例输出
6 4 7
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
int map[51][51],book[51],dis[51];
int main()
{
int n,m;
while(cin>>n>>m)
{
for(int i=0;i<n;i++) //输入
for(int j=0;j<n;j++)
{
cin>>map[i][j];
if(i!=j&&map[i][j]==0)
map[i][j]=0x3f3f3f3f;
}
memset(book,0,sizeof(book));
for(int i=0;i<n;i++) dis[i]=map[m][i];//第一步
for(int i=0;i<n;i++)
{
int minn=0x3f3f3f3f,date;
for(int j=0;j<n;j++)
if(book[j]==0&&dis[j]<minn) //第二步 找
minn=dis[j],date=j;
book[date]=1;
for(int j=0;j<n;j++)
if(book[j]==0&&dis[j]>dis[date]+map[date][j]) //第三步 更新
dis[j]=dis[date]+map[date][j];
}
for(int i=0;i<n;i++)
if(i!=m)
{
if(dis[i]!=0x3f3f3f3f) cout<<dis[i]<<" ";
else cout<<-1<<" ";
}
cout<<endl;
}
return 0;
}