图论入门小结
1.传递闭包
和弗洛伊德一样的三个循环...不过从三角形松弛变成了判断两个点是否都有一条到某一个中间节点的路径,若有则两点联通. 复杂度n^3
2.弗洛伊德 任意两点间最短路
三角形性质 dis[x]+len[x][y]>=dis[y];//某一点到x的距离+x与y之间的距离>=该点到y的距离
松弛就是把不满足上述要求的最短距离改为满足的...
View Code
没有相连的边则权值为正无穷,用memset全部初始化为10即可;
复杂度n^3
三个循环,中间节点放最外面
1 for(){// k的循环 2 for(){// i的循环 3 for(){// j的循环 4 if(dis[i][k]+dis[k][j]>=dis[i][j]){ 5 dis[i][j]=dis[i][k]+dis[k][j]; 6 } 7 } 8 } 9 }
初始化:
自己到自己的距离为0;
163博客真的对强迫症太不友好了QAQ手动缩进浑身难受.
3.迪杰斯特拉 单源最短路 可用堆优化虽然还不会但是还是要大写加粗
邻接表和矩阵都可以用
要求不能有负权
1.找距离所求点最短距离的点;
2.然后以该点为中间点对其他所有未访问的点做松弛同时对该点做访问过的标记;
3.如果能找到没有访问过的点,返回1,否则结束;
复杂度n^2.
1 void work(int st){ 2 for(int i=1;i<=n;i++){ 3 dis[i]=maps[st][i]; 4 } 5 memset(vis,0,sizeof(vis)); 6 vis[st]=1; 7 dis[st]=0; 8 for(int i=1;i<=n;i++){ 9 int minn=99999999; 10 int k=0; 11 for(int j=1;j<=n;j++){ 12 if(dis[j]<=minn&&(!vis[j])){ 13 minn=dis[j]; 14 k=j; 15 } 16 } 17 if(k==0){ 18 return; 19 } 20 vis[k]=1; 21 for(int j=1;j<=n;j++){ 22 if((maps[k][j]+dis[k]<=dis[j])&&(!vis[j])){ 23 dis[j]=dis[k]+maps[st][j]; 24 } 25 } 26 } 27 }
4.Bellman_ford算法 判断是否有负环
5.SPFA 改进上面的
4用边表
5用邻接表+队列
p196自己翻书好了.....
6.最小生成树
p200