- [P5908 猫猫和企鹅](https://www.luogu.com.cn/problem/P5908)
- [P1395 会议](https://www.luogu.com.cn/problem/P1395)
- [P3379 【模板】最近公共祖先(LCA)](https://www.luogu.com.cn/problem/P3379)
- [P2052 [NOI2011] 道路修建](https://www.luogu.com.cn/problem/P2052)
- [P5836 [USACO19DEC]Milk Visits S](https://www.luogu.com.cn/problem/P5836)
板子:
#include<queue>
#include<vector>
#include <iostream>
using namespace std;
const int MAXN = 1e3;
typedef struct edge {
int v, w;
edge(int v0, int w0):v(v0),w(w0){}
bool operator>(const edge& b)const {
return w > b.w;
}
/*这段代码是 C++ 中的运算符重载代码,它重载了 ">" 运算符
用于比较两个 edge 类型对象的大小
const 关键字,表示该函数不会修改类的成员变量
参数 b 是一个 edge 对象的引用,表示要与当前对象进行比较的另一个对象。
函数体中的比较语句 "w > b.w" 判断当前对象的 w 成员变量是否大于参数对象 b 的 w 成员变量
如果是,则返回 true,否则返回 false
用于排序算法中,例如在 Kruskal 算法和 Prim 算法中对边权进行排序,找到最小生成树。*/
}edge;
int n;//点数
int dist[MAXN + 10];
int in[MAXN + 10];
//判断是否在队列中
vector<edge> G[MAXN + 10];//存储图
void spfa(int p_s) {
queue<int>Q;//
/*这段代码使用了 C++ STL 中的队列(queue)容器,用于实现一个拓展队列。
声明了一个名为 Q 的队列对象,其元素类型为 int 类型。
在程序中,可以使用 Q.push(x) 来将 x 放入队列尾部,
使用 Q.front() 来获取队首元素,
使用 Q.pop() 来弹出队首元素,
使用 Q.empty() 来判断队列是否为空。
在图搜索算法中,拓展队列是非常常见的数据结构,
用于存储待扩展的节点或状态,
通常使用广度优先搜索算法(BFS)和
宽度受限的深度优先搜索算法(IDS)来遍历图或搜索问题的解空间。*/
for (int i = 1; i <= n; i++) {
//初始化dist,in
dist[i] = 0x3f3f3f3f;//定义为无穷大
in[i] = 0;
}
Q.push(p_s);//初始化
dist[p_s] = 0;
in[p_s] = 1;
while (!Q.empty()) {
int ft = Q.front();
Q.pop();
in[ft] = 0;
for (int i = 0; i < G[ft].size(); i++) {
//遍历每一条边
if (dist[G[ft][i].v] > dist[ft] + G[ft][i].w) {
dist[G[ft][i].v] = dist[ft] + G[ft][i].w;
if (!in[G[ft][i].v]) {
//更新队列,不在队列入队
Q.push(G[ft][i].v);
in[G[ft][i].v] = 1;
}
}
}
}
}
//Dijkstra
void dijkstra(int p_s) {
//p_s为起点下标
for (int i = 1; i < n; i++) {
//in初始化
dist[i] = 0x3f3f3f3f;
in[i] = 0;
}
dist[p_s] = 0;
for (int iii = 0; iii <= n; iii++) {
//findmin
int minn = 0x3f3f3f3f;
int minpos = 0;
for (int i = 1; i <= n; i++) {
if (!in[i] && dist[i] < minn) {
minn = dist[i];
minpos = i;
}
}
if (minpos == 0) {
cout << "非连通图" << endl;
break;
}
//最近点入集合并更新
in[minpos] = 1;
for (int i = 0; i < G[minpos].size(); i++) {
int v = G[minpos][i].v;
if (dist[v] > minn + G[minpos][i].w) {
dist[v] = minn + G[minpos][i].w;
}
}
}
}
//Floyd
int dp[MAXN + 10][MAXN + 10];
void floyd() {
for (int k = 1; k <= n; k++) {
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= n; j++) {
if (dp[i][j] > dp[i][k] + dp[k][j]) {
dp[i][j] = dp[i][k] + dp[k][j];
}
}
}
}
}
int main()
{
ios::sync_with_stdio(false);
int T, N;
//边数与点数
cin >> T >> N;
n = N;
for (int i = 0; i < T; i++)
{
int v1, v2, w;
cin >> v1 >> v2 >> w;
G[v1].push_back(edge(v2, w));
G[v2].push_back(edge(v1, w));
}
spfa(N);
//以N为起点的单源最短路径
for (int i = 1; i <= n; i++)
{
cout << "N__>" << i << ": ";
cout << dist[i] << endl;
}
return 0;
}