板子题目练习(洛谷)

- [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;

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

苏生十一_Nojambot

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值