先行提示:图论题目中有可能两个点之间有直接相连的权值不同的边,一定要取最小值存到a[][]里!
A.Dijkstra算法
1.数据结构的准备
#include<stdio.h>
#include<string.h>
int a[1000][1000]; //储存从i到j边的长度
int dis[1000]; //储存从一条特定边到其他任一边的长度
//注意!起点是哪条边,dis[那条边] = 0;
int path[1000] ={0};
int vis[1000] = {0};//用于存储是否已经被访问
int n = 0;
const int inf = 0x3f3f3f3f;
注意:inf(infinite)一般定义为0x3f3f3f3f,在memset时,无限大经常用0x3f.
2.核心算法的实现
void dijkstra(){
for(int i = 0;i < n;i++){//focus infinite loop
//printf("1");
int min = inf,minp = 0;//focus: min = inf
for(int i = 0;i < n;i++){
if(vis[i]) continue;
if(dis[i] < min){
min = dis[i];//没有被访问过的最短的边的另一点作为研究点
minp = i;
}
}
vis[minp] = 1;//已经被访问
//update the min of edge
for(int i = 0;i < n;i++)
{ //focus:use the "min"
if(vis[i] == 0 && min + a[minp][i] < dis[i]){
dis[i] = dis[minp] + a[minp][i];
path[i] = minp;
}
}
}
}
注意,最外层不能用while判断是否所有vis全为1,因为可能到了最后,vi还是无穷大,这样我没最终也没用以它作为研究点,但Dijkstra算法又确确实实结束了。所以最外层要用for循环进行n-1次。
B.Floyd算法
......