张昊_2404020207_网络24_2 level
获赞
0
粉丝
0
关注
1
看过 TA
4
哈尔滨理工大学
2028
C++
IP属地:黑龙江
暂未填写个人简介
私信
关注
2024-11-26 21:54
哈尔滨理工大学 C++
1.dijkstra(无法求负边)#include<bits/stdc++.h>using namespace std;#define endl '\n'const int N = 3e5;int n, m, s, t;vector<pair<int, int> > g[N];int dis[N];int st[N];void dij() {memset(dis,0x3f,sizeof(dis));priority_queue<pair<int,int>,vector<pair<int,int>>,greater<pair<int,int>>> pq;pq.push({0,s});while (pq.size()){int  d = pq.top().first;int  u = pq.top().second;pq.pop();if (st[u])continue;st[u] = 1;for (auto i : g[u]){int v = i.first;int w = i.second;if (dis[v] > d + w){dis[v] = d + w;pq.push({dis[v],v});}}}cout << dis[t];}signed main(){std::ios::sync_with_stdio(false);cin.tie(0); cout.tie(0);cin >> n >> m >> s >> t;for (int i = 0;i <m;i++){int u, v, w;cin >> u >> v >> w;g[u].push_back({v,w});g[v].push_back({u,w});}dij();return  0;}2.贝尔特佛特(可以求负边)int n, m;       // n表示点数,m表示边数int dist[N];        // dist[x]存储1到x的最短路距离struct Edge     // 边,a表示出点,b表示入点,w表示边的权重{int a, b, w;}edges[M];// 求1到n的最短路距离,如果无法从1走到n,则返回-1。int bellman_ford(){memset(dist, 0x3f, sizeof dist);dist[1] = 0;// 如果第n次迭代仍然会松弛三角不等式,就说明存在一条长度是n+1的最短路径,由抽屉原理,路径中至少存在两个相同的点,说明图中存在负权回路。for (int i = 0; i < n; i ++ ){for (int j = 0; j < m; j ++ ){int a = edges[j].a, b = edges[j].b, w = edges[j].w;if (dist[b] > dist[a] + w)dist[b] = dist[a] + w;}}if (dist[n] > 0x3f3f3f3f / 2) return -1;return dist[n];}3.Floyd(dp思想)for (k = 1; k <= n; k++) {for (x = 1; x <= n; x++) {for (y = 1; y <= n; y++) {f[x][y] = min(f[x][y], f[x][k] + f[k][y]);}}}上述算法,dijkstra时间复杂度最低,Floyd最好n的三次方,但是可以求图上连通点之间的最短距离
0 点赞 评论 收藏
分享
2024-11-26 21:50
哈尔滨理工大学 C++
#include <iostream>#include <vector>#include <algorithm>using namespace std;// 定义边的结构体struct Edge {int u, v, w; // 边的起点、终点和权重};// 比较函数,用于排序边bool operator<(const Edge& a, const Edge& b) {return a.w < b.w;}// 并查集的父节点数组int parent[100005];// 查找根节点int find(int x) {return parent[x] = find(parent[x]);}// 合并两个集合void merge(int x, int y) {int px = find(x), py = find(y);if (px != py) parent[px] = py;}int main() {int n, m; // n为顶点数,m为边数cin >> n >> m;// 读取所有边vector<Edge> edges(m);for (int i = 0; i < m; i++) {cin >> edges[i].u >> edges[i].v >> edges[i].w;}// 按照边的权重排序sort(edges.begin(), edges.end());// 初始化并查集for (int i = 0; i <= n; i++) parent[i] = i;long long ans = 0; // 最小生成树的总权重int cnt = 0; // 已经加入最小生成树的边数// 遍历所有边for (auto& e : edges) {int pu = find(e.u), pv = find(e.v);if (pu != pv) {merge(pu, pv);ans += e.w;cnt++;}if (cnt == n - 1) break; // 如果已经加入 n-1 条边,停止}// 输出结果if (cnt == n - 1) {cout << ans << endl;} else {cout << "IMPOSSIBLE" << endl; // 如果无法形成最小生成树}return 0;}
0 点赞 评论 收藏
分享

创作者周榜

更多
关注他的用户也关注了:
牛客网
牛客网在线编程
牛客网题解
牛客企业服务