4 5
1 2 3
1 3 5
1 4 7
2 4 2
3 4 1
#include
#include
using namespace std;
const int INF = 10000;
int edge[50][50];
int dis[50];//d表示源节点到该节点的最小距离
bool vis[50];//v标记访问过的节点
int n, m;//n代表点数 m代表边数
int main()
{
freopen("in.txt", "r", stdin);
scanf("%d%d", &n, &m);
int min;
int x, y, d;
memset(edge, INF, sizeof(edge)); //使用一个值初始化无限大
memset(dis, INF, sizeof(dis));
memset(vis, false, sizeof(vis));
for(int i = 0; i < m;i++) {
scanf("%d%d%d", &x, &y, &d);
edge[x][y]=d;
edge[y][x]=d;
}
dis[1]=0; //使用1作为源顶点 距离置0
//类似冒泡
for(int i = 1, k; i <= n; i++) {
min = INF;
for(int j = 1; j <= n; j++) {
if(!vis[j] && dis[j] < min) {
min = dis[j];
k = j;
}
}
vis[k] = true;
//松弛操作调整
for(int j = 1; j <= n; j++) {
if(!vis[j] && edge[k][j] != INF && dis[j] > dis[k] + edge[k][j]) {
dis[j] = dis[k] + edge[k][j];
}
}
}
//最终输出从源节点到其他每个节点的最小距离
for(int i = 1; i <= n; i++)
printf("%d->%d: %d\n", 1, i, dis[i]);
return 0;
}
1->1: 0
1->2: 3
1->3: 5
1->4: 5
#include
#include
#include
#include
using namespace std;
//定义邻接表
struct edge {
int v, d; //顶点 权值
edge(int v_, int d_): //初始化
v(v_), d(d_) { }
};
//优先队列生成最短路径结构体
struct queue_element {
int v;
int d;
queue_element(int v_, int dis_value_):
v(v_), d(dis_value_) { }
bool operator <(const queue_element &other) const {
return d > other.d; //重载操作符, 距离大的优先级靠后
}
};
int dis[50];
bool vis[50];
vector<edge> edges[50];
int n, m;
void Djikstra(int v) {
memset(dis, 0x3f, sizeof(dis)); //各类初始化
memset(vis, false, sizeof(vis));
priority_queue<queue_element> q;
q.push(queue_element(v, 0));//首先把源顶点压入优先队列
while (!q.empty()) {
queue_element t = q.top();
q.pop();
if (vis[t.v]) {
continue; //如果已访问过则扔掉 继续下一个
}
vis[t.v] = true;//更新访问标志
dis[t.v] = t.d; //保存路径
//松弛操作 更新最短路径
vector<edge>::iterator it;
for (it = edges[t.v].begin(); it != edges[t.v].end(); ++it) {
q.push(queue_element(it->v, t.d + it->d)); //压入顶点距离 自动排序
}
}
//最终输出从源节点到其他每个节点的最小距离
for(int i = 1; i <= n; i++){
if (i != v) {
printf("%d->%d:%d\n",v, i, dis[i]);
}
}
cout << endl;
}
int main()
{
freopen("in.txt", "r", stdin) ;
scanf("%d%d",&n,&m);
int x, v, d;
//建立邻接表
for(int i=0;i<m;i++)
{
scanf("%d%d%d",&x,&v,&d);
edges[x].push_back(edge(v, d));
edges[v].push_back(edge(x, d));
}
//每个节点都当做一次源节点
for (int i = 1; i <= n; i++) {
Djikstra(i);
}
return 0;
}
1->2:3
1->3:5
1->4:5
2->1:3
2->3:3
2->4:2
3->1:5
3->2:3
3->4:1
4->1:5
4->2:2
4->3:1
迪杰斯特拉在求最短路径时, 经常使用到, 但是比赛时会害怕爆时间, 只能来学这看不懂 装逼 的算法, 我一个比赛转C++小白, 直接从一个优化过的算法, 学到了vector创建邻接表, 操作符重载, 优先队列, 迭代器, 结构体重载初始化. 脑子废了
不懂或者有错误请及时提问哦~
共勉