单源最短路径Dijkstra算法
- 定义一个数组dist[],存储当前最短路径 :dist[s]=0,其他dist[i]=+∞【INT_MAX]
- 遍历起点的所有的边,更新dist
- 下一个节点的选择,dist[i]最小且未访问过【用一个小根堆】维护
- 循环2-3,得到最终的dist
题目——还是畅通工程
描述:
给定一个无向连通图和其中的所有的边,判断这个图的所有顶点是否是联通的
输入:
每组数据的第一行是两个整数n和m(0<=n<=1000),n表示图的顶点数目,m表示图中边的数目,随后有m行数据,每行有两个值x和y(0<x,y<=n),表示顶点x和y相邻,顶点的编号从1开始计数。输入不保证这些边是否重复。
输出:
对每组输入数据,若所有顶点都是联通的,就输出"YES",否则输出"NO"
#include<cstdio>
#include<vector>
#include<climits>
#include<queue>
#define N 300
using namespace std;
struct Edge {
int y;
int weight;
};
struct Node {
int dist;
int x;
};
bool operator<(Node lhs, Node rhs) {
return lhs.dist > rhs.dist;
}
vector<Edge>graph[300];
int dijkstra(int s, int t, int n) {
int dist[N];
bool isvisit[N];
for (int i = 0; i < n; i++) {
dist[i] = INT_MAX;
isvisit[i] = false;
}
priority_queue<Node>pqueue;//第一次访问到某个节点的时候,再把他放在优先队列中
//第一个入队的节点是起点
dist[s] = 0;
Node node;
node.dist = dist[s];
node.x = s;
pqueue.push(node);
while (pqueue.empty() == false) {
int x = pqueue.top().x;
pqueue.pop();
if (isvisit[x] == true) {
continue;
}
isvisit[x] = true;
for (int i = 0; i < graph[x].size(); i++) {
//以x起点的所有的关联边
int y=graph[x][i].y;
int weight = graph[x][i].weight;
//如果起点到y的距离大于先到x再到y的距离
if (dist[y] > dist[x] + weight) {
dist[y] = dist[x] + weight;
node.dist = dist[y];
node.x = y;
pqueue.push(node);
}
}
}
if (dist[t] != INT_MAX) {
return dist[t];
}
else {
return -1;
}
}
int main() {
int n, m;
while (scanf_s("%d%d", &n, &m) != EOF) {
for (int i = 0; i < n; i++) {//清理每个链中的残留
graph[i].clear();
}
for (int i = 0; i < m; i++) {
int x, y, weight;
scanf_s("%d%d%d", &x, &y, &weight);
//将边的信息填入链表
Edge edge;
edge.y = y;
edge.weight = weight;
graph[x].push_back(edge);
edge.y = x;
graph[y].push_back(edge);
}
int s, t;
}
}