C++实现SPFA和dijikstr算法

来源:互联网 发布:linux tftp 配置 编辑:程序博客网 时间:2024/05/16 08:13

看了B站上卿学姐的视频,学着写了写

先是SPFA:

#include<iostream>#include<vector>#include<queue>using namespace std;const int maxz = 205;vector<pair<int, int>>E[maxz];int inq[maxz],dis[maxz];int n, m;void inti()//初始化领接表{for (int i = 0; i < maxz; ++i) E[i].clear();//先清空每一个vector<pair<int,int>>for (int i = 0; i < maxz; ++i) inq[i] = 0;//再清空点队列for (int i = 0; i < maxz; ++i)dis[i] = 1e9;//再初始化距离数组}int main(){inti();//初始化while (cin >> n >> m)//n为点数,m为边数{for (int i = 1; i <= m; ++i)//先初始化每条边{int x, y, k;//点x,点y,距离kscanf("%d%d%d",&x,&y,&k);E[x].push_back(make_pair(y, k));//将x到y的边的长度更新为kE[y].push_back(make_pair(x, k));//将y到x的边的长度也更新为k}//完成领接表的建立int s, t;//起点s和终点tqueue<int> q;//用于优化算法的队列qq.push(s);//先将起点s入队inq[s] = 1;//再记录起点s已入队dis[s] = 0;//s到s的距离当然为0while (!q.empty())//如果队列不为空的话{int now;now = q.front();//取队列中的第一个元素q.pop();//队首元素出队inq[now] = 0;//记录出队for (int i = 1; i <= E[now].size(); ++i)//通过我们出队的这个点来更新对每个点的路径权值{int v = E[now][i].first;//记录now-v中的vif (dis[v] > dis[now] + E[now][i].second)//如果以前从s到v点的距离大于了先经过now点再到v点的距离dis[v] = dis[now] + E[now][i].second;//那就更新dis[v]if (inq[v] == 1)continue;//如果v点已经在队列中,则不作操作else inq[v] = 1,q.push(v);//否则将v点加入队列中}}if (dis[t] == 1e9)printf("-1");//如果还是到不了,则寻找最短路失败else printf("%d\n",dis[t]);//否则输出找到的最短路的值}return 0;}

再是dijikstr:

#include<iostream>#include<vector>#include<queue>using namespace std;const int maxz = 205;vector<pair<int, int>>E[maxz];int dis[maxz];int n, m;void inti()//初始化领接表{for (int i = 0; i < maxz; ++i) E[i].clear();//先清空每一个vector<pair<int,int>>for (int i = 0; i < maxz; ++i)dis[i] = 1e9;//再初始化距离数组}int main(){inti();//初始化while (cin >> n >> m)//n为点数,m为边数{for (int i = 1; i <= m; ++i)//先初始化每条边{int x, y, k;//点x,点y,距离kscanf("%d%d%d",&x,&y,&k);E[x].push_back(make_pair(y, k));//将x到y的边的长度更新为kE[y].push_back(make_pair(x, k));//将y到x的边的长度也更新为k}//完成领接表的建立int s, t;//起点s和终点tpriority_queue<pair<int,int>> q;//用优先队列dis[s] = 0;//s到s的距离当然为0q.push(make_pair(-dis[s],s));//优先队列优先级最高的是最大的元素,我们存的时候取反,于是优先级最高的元素就成为了原本最大的元素,也即离选定起点最近的元素while (!q.empty())//如果队列不为空的话{int now;now = q.top().second;//取队列中的第一个元素q.pop();//队首元素出队for (int i = 0; i < E[now].size(); ++i)//通过我们出队的这个点来更新对每个点的路径权值{int v = E[now][i].first;//记录now-v中的vif (dis[v] > dis[now] + E[now][i].second)//如果以前从s到v点的距离大于了先经过now点再到v点的距离{dis[v] = dis[now] + E[now][i].second;//那就更新dis[v]q.push(make_pair(-dis[v],v));//讲用到的点更新进队列,由于选择的点都是按照距离最近来选取的,所以不用担心之后会重复入队}}}if (dis[t] == 1e9)printf("-1");//如果还是到不了,则寻找最短路失败else printf("%d\n",dis[t]);//否则输出找到的最短路的值}return 0;}