邻接矩阵版
const int MAXV=1000;//最大顶点数
const int INF=1000000000;
int n,G[MAXV][MAXV];//n为顶点数,MAXV为最大顶点数
int d[MAXV];//起点到达各点的最短路径长度
int pre[MAXV];//pre[v]表示从起点到顶点v的最短路径上v的前一个顶点
bool vis[MAXV]={false};//标记数组,vis[i]==true表示已访问。初值均为false
void Dijkstra(int s)//s为起点
{
fill(d,d+MAXV,INF);//fill函数将整个d数组赋为INF
d[s]=0;//起点s到达自身的距离为0
for(int i=0;i<n;i++)//循环n次
{
int u=-1,MIN=INF;//u为距离最小的顶点序号,MIN存放该最小的d[u]
for(int j=0;j<n;j++)
{
if(vis[j]==false&&d[j]<MIN)//找到未访问的顶点中距离最小的,一开始是起点
{
u=j;
MIN=d[j];
}
}
//找不到小于INF的距离,说明剩下的顶点和起点s不连通
if(u==-1) return;
vis[u]=true;//标记u为已访问
for(int v=0;v<n;v++)
{
//如果v未访问&&能到达v&&以u为中介点可以使d[v]更优
if(vis[v]==false&&G[u][v]!=INF&&d[u]+G[u][v]<d[v]){
d[v]=d[u]+G[u][v];//优化v的距离
pre[v]=u;//记录v的前驱顶点是u
}
}
}
void DFS(int s,int v)
{
if(v==s)
{
printf("%d\n",s);
return;
}
DFS(s,pre[v]);
printf("%d\n",v);
}
邻接表版
struct Node
{
int v,dis;
};
vector<Node> Adj[MAXV];
int n;
int d[MAXV];
bool vis[MAXV]={false};
void Dijkstra(int s)//s为起点
{
fill(d,d+MAXV,INF);//fill函数将整个d数组赋为INF
d[s]=0;//起点s到达自身的距离为0
for(int i=0;i<n;i++)//循环n次
{
int u=-1,MIN=INF;//u为距离最小的顶点序号,MIN存放该最小的d[u]
for(int j=0;j<n;j++)
{
if(vis[j]==false&&d[j]<MIN)//找到未访问的顶点中距离最小的,一开始是起点
{
u=j;
MIN=d[j];
}
}
//找不到小于INF的距离,说明剩下的顶点和起点s不连通
if(u==-1) return;
vis[u]=true;//标记u为已访问
for(int j=0;v<Adj[u].size();j++)
{
int v=Adj[u][j].v;
//如果v未访问&&以u为中介点可以使d[v]更优
if(vis[v]==false&&d[u]+Adj[u][j].dis<d[v])
d[v]=d[u]+Adj[u][j].dis;//优化v的距离
}
}
}
例题
- 输入
输入的第一行包含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>
using namespace std;
const int MAXV=1000;//最大顶点数
const int INF=1000000000;
int n,G[MAXV][MAXV];//n为顶点数,MAXV为最大顶点数
int d[MAXV];//起点到达各点的最短路径长度
bool vis[MAXV]= {false}; //标记数组,vis[i]==true表示已访问。初值均为false
void Dijkstra(int s)//s为起点
{
fill(d,d+MAXV,INF);//fill函数将整个d数组赋为INF
d[s]=0;//起点s到达自身的距离为0
for(int i=0; i<n; i++) //循环n次
{
int u=-1,MIN=INF;//u为距离最小的顶点序号,MIN存放该最小的d[u]
for(int j=0; j<n; j++)
{
if(vis[j]==false&&d[j]<MIN)//找到未访问的顶点中距离最小的,一开始是起点
{
u=j;
MIN=d[j];
}
}
//找不到小于INF的距离,说明剩下的顶点和起点s不连通
if(u==-1)
return;
vis[u]=true;//标记u为已访问
for(int v=0; v<n; v++)
{
//如果v未访问&&能到达v&&以u为中介点可以使d[v]更优
if(vis[v]==false&&G[u][v]!=0&&d[u]+G[u][v]<d[v])
d[v]=d[u]+G[u][v];//优化v的距离
}
}
}
int main()
{
int u;
int s;
while(scanf("%d%d",&n,&s)!=EOF)
{
fill(G[0],G[0]+MAXV*MAXV,INF);
fill(vis,vis+MAXV,false);
for(int i=0; i<n; i++)
{
for(int j=0; j<n; j++)
{
scanf("%d",&u);
G[i][j]=u;
}
}
Dijkstra(s);
for(int i=0; i<n; i++)
{
if(i!=s)
{
if(d[i]!=INF)
printf("%d ",d[i]);
else
printf("-1 ");
}
}
printf("\n");
}
return 0;
}