给大家一个参考
#include <cstring>
#include <iostream>
#include <queue>
using namespace std;
const int MAXN = 510, MAXM = 2 * 1e5 + 10, INF = 0x3f3f3f3f;
typedef pair<int, int> PII;
int h[MAXM], e[MAXM], w[MAXM], ne[MAXM], idx;
bool vis[MAXN];
int n, m;
void add(int a, int b, int c) {
e[idx] = b, w[idx] = c, ne[idx] = h[a], h[a] = idx ++ ;
}
int Prim()
{
memset(vis, false, sizeof vis);
int sum = 0, cnt = 0;
priority_queue<PII, vector<PII>, greater<PII>> q;
q.push({0, 1});
while (!q.empty())
{
auto t = q.top();
q.pop();
int ver = t.second, dst = t.first;
if (vis[ver]) continue;
vis[ver] = true, sum += dst, ++cnt;
for (int i = h[ver]; i != -1; i = ne[i])
{
int j = e[i];
if (!vis[j]) {
q.push({w[i], j});
}
}
}
if (cnt != n) return INF;
return sum;
}
int main()
{
cin >> n >> m;
memset(h, -1, sizeof h);
for (int i = 0; i < m; ++i)
{
int a, b, w;
cin >> a >> b >> w;
add(a, b, w);
add(b, a, w);
}
int t = Prim();
if (t == INF) cout << "impossible" << endl;
else cout << t << endl;
}
为什么有人说优化了个寂寞,因为答主把每条边都进队了,和之前其实没啥区别,
加一个dist数组会更好,加入堆中的起码要比之前更新的到生成树的距离要小
这样就可以减少很多条边入堆dl,我想问一下cnt是记录次数还是什么?为什么只需要在最后判断cnt!=n就可以断定不连通?
cnt应该是记录当前答案生成树中点的个数(因为堆优化类似dijkstra堆优化,所以出队就是确定当前点加入了,所以最后不为n,就是不连通吧
你好请问你是怎么处理重边的呢,为什么你的代码
可以过
%%%%
博主你这个堆优化了个寂寞,为什么我没有用堆123ms,用了你的之后823ms
应该是因为稠密图吧
应该博主重复进队造成的,如果用dist加以判断的话,时间有关也就120多ms
为啥cnt最终要判断是不是等于n而不是n-1?不是n个点n-1条边吗
它这里判断的就是点,不是边,目标是把所有点都放到树中,而且边有 m 条
强的,高赞都是用邻接矩阵,博主用 邻接表结构简单,复用Dijkstra方式,集成优化实现,目前看到最赏心悦目的解法
博主用的不是邻接表,他这个是链式前向星
tql