昨天亲口立下的誓言,不能第一天就打脸呀。今天是我第一天备战,讲真是真的心累。一整天,我仅仅看会了两个知识点。还不是应用到题目上,仅仅是两个答题模板而已。最短路径中的Dijkstra算法与Dijkstra算法的堆优化。
说到答题模板,是我今天新发现的,来自于大神f_zyj的总结:ACM在线模板(附上链接https://blog.csdn.net/f_zyj/article/details/51594851)。对于她的模板代码,做一点小的改动,添加适当注释,另外写成一个可运行的源程序。
#include<iostream>
#include<cstring>
using namespace std;
const int MAX = 100;
int n,m;
int graph[MAX][MAX];
int visit[MAX];
int dist[MAX];
void dijkstra(int s){//起点
for (int i = 0; i < n; i++) //初始化
{
dist[i] = INF; //定义s到所有点的最短距离都为无穷
visit[i] = false;
}
dist[s] = 0; //初始化s点到自己的最短距离为0
for (int j = 0; j < n; j++) //循环次数
{
int k = -1;
int min = INF;
for (int i = 0; i < n; i++) //此循环用来每次找出s到未访问过节点的最短距离
{
if (!visit[i] && dist[i] < min)
{
min = dist[i];
k = i;
}
}
if (k == -1)
{
break;
}
visit[k] = true;
for (int i = 0; i < n; i++) //此循环主要用来判断是否存在一条路径,比当前s到某节点的距离更短
{
if (!visit[i] && dist[k] + graph[k][i] < dist[i]) //松弛操作
{
dist[i] = dist[k] + graph[k][i];
}
}
}
}
int main(){
cin>>n>>m; //输入点数与边数
memset(graph,MAX,sizeof(graph));
for(int i=0;i<m;i++){
int x,y,z;
cin>>x>>y>>z; //输入两个点与中间的连线
graph[x][y]=graph[y][x]=z; //这里定义的是带权无向图(不含负权值)
}
dijkstra(0); //这里假设求每个节点到节点0的最短路径
for(int i=0;i<n;i++){
cout<<dist[i]<<endl; //输出每个节点到节点0的最短路径长度
}
return 0;
}
另外这里还想说一下无穷这个概念,在一些题目中,有些地方需要设置一个无穷大的值,但是这个值不是随便确定的,我们可以选择适合的一个值:采用十六进制的0x3f3f3f3f。具体为什么这样使用,可以参考我找的这篇博客:https://blog.csdn.net/jiange_zh/article/details/50198097
实在不想写堆优化的Dijkstra算法了(有点太晚了~~~~),等明天总结吧。不要看我刚开始说看了一天算法,但这里只总结这点东西,其实自认为自己不是那么聪慧(非常委婉的“夸”下自己),好多时候都是在思考程序的每一个步骤,因为之前并没有太多的培养,所以真的很慢,考虑起来也很慢,希望自己可以慢慢习惯。说一个看程序比较好的方法,就是按程序走一个自己的测试用例(比如这里,自己规定一个无向图,然后按着程序代码,模拟程序执行过程),千万不要嫌麻烦,有时候这可能是最好的方法!!!
最后给再给大家推荐一个今天新发现的博主,此博主特点就是:把蓝桥杯练习题库整理的非常非常好
附上链接:https://blog.csdn.net/rodestillfaraway/article/details/50533742