Dijkstra Algorithm
利用dijkstra算法,求解无向图中某个顶点到达其他顶点的最短路径权值
//利用邻接表存储图
#include<iostream>
#include<algorithm>
#define INF 0x3fffffff
using namespace std;
const int maxn=100;
typedef struct node{
int edge;
int point;
}Node;
int n;//the total number of vertices
int dp[maxn];
bool vis[maxn]={false};
vector<Node> MAP[maxn];//record the map
void dijkstra(int s) // strat point
{
fill(dp,dp+n,INF);
dp[s]=0;
for(int i=0;i<n;i++) //traversal n nodes
{
int MIN=INF;
int u=-1;//relay node
for(int j=0;j<n;j++)
{
if(dp[j]<MIN && vis[j] == false )//寻找中继节点,且此点上的权值最小(此权值是从s点出发的权值,已经加上了从s点到其的边权值)
{
MIN=dp[j];
u=j;
}
}
if(u==-1) return ;//找不到小于INF的dp[u],说明剩下的顶点和起点S不连通
vis[u]=true; //标记中继节点u已访问
for(int k=0;k<MAP[u].size();k++) //此循环是给当前中继节点u所能到达的所有节点赋值(所赋的值是从S点到u点的边权值加上u点到其他点的边权值),
{ //如此便将u点所能联通的点已经赋值了从s点到其的值
if(MAP[u][k].edge+dp[u]<dp[MAP[u][k].point] && vis[MAP[u][k].point] == false)//中继节点的值大小加上到此点边权值大小,小于此点之前已有的权值大小
//(此点已有的权值大小,是通过之前的循环过程中所找到的,比如第一次循环是寻找S点所能到达的所有点,若s能到达此点,则更新了此点的权值大小,
//第二轮循环中中继节点若也能到达此点,则比较中继节点到达此点权值大小和第一轮s点直接到达此点的大小,小的则更新权值,
//如此便实现了比较中继节点到达当前所能到达的点的权值大小和之前已经到达了此点的权值进行比较,从而更新一个最小值)
{
// MIN=MAP[u][k].edge+dp[u];
dp[MAP[u][k].point]=MAP[u][k].edge+dp[u];
}
}
}
}
int main()
{
cout<<"please input the total number of nodes:";
cin>>n; //input the total number of nodes
cout<<"please input the start node(from 0 to maximum node minus 1):";
int s;//start point
cin>>s; //input the start point
cout<<"please input the total number of edges:";
int e;//the total number of edges
cin>>e;
//input the map about nodes and corresponding weights;
cout<<"please input the map(eg.:1 2 3 represent node 1 to node 2 and corresponding weight is 3,the maximum input is the size of edge):"<<endl ;
for(int i=0;i<e;i++) //在存入节点1至2的边权值时,应当同时存入2到1的边权值,因为dijkstra 算法只能求解无向图
{
int a;
int b;
int c;
cin>>a>>b>>c;
Node t;
t.point=b;
t.edge=c;
MAP[a].push_back(t);
t.point=a;
MAP[b].push_back(t);
}
dijkstra(s);
//finally, the shortest weight from start point s to all of other points will save in the array dp;
printf(" the shortest weight from node %d to other node, respectively, as shown below:\n",s);
for(int i=0;i<n;i++)
{
cout<<dp[i]<<' ';
}
}
需要注意的是,图的存储,无向图应当存两边的值。
此处输入的图如下所示:
当输入:
0 1 1
2 1 2
3 1 3 时,若没有双向赋值,则为单边节点,此时为一个有向图节点0 和2,3不可达,于是输出最大值INF。
双向赋值后,为无向图,此时则可达:
//利用邻接矩阵存储