题目链接:点击打开链接
复杂度:O(MlogM) (M为边数),未优化时复杂度为O(N^2)
首先把1这个点标记为已访问,把它所连的边都加到优先队列里边,然后每次从优先队列顶端拿终点未访问的边,把终点标记成已访问,把终点连的边放进优先队列,直到无边可拿或所有点均访问过为止。
代码:参考别人的代码.. https://blog.csdn.net/jhgkjhg_ugtdk77/article/details/47081375
#include<iostream>
#include <cstdio>
#include <cstring>
#include <queue>
#include <algorithm>
#include <cmath>
#include <queue>
#include <map>
using namespace std;
const int maxn = 1000005;
struct Edge{
int from,to,len;
Edge(int x,int y,int l){
this -> from = x;
this -> to = y;
this -> len = l;
}
friend bool operator<(Edge a,Edge b){
return a.len>b.len;
}
};
priority_queue<Edge> pq;
vector<Edge> graph[maxn];
bool vis[maxn];
int n,m;
int main(){
scanf("%d%d",&n,&m);
int x,y,l;
for(int i=1; i<=m; i++){
scanf("%d%d%d",&x,&y,&l);
graph[x].push_back(Edge(x,y,l));
graph[y].push_back(Edge(y,x,l));
}
while(!pq.empty()) pq.pop();
for(int i=0; i<graph[1].size(); i++){
pq.push(graph[1][i]);
}
vis[1] = true;
int left = n;
int ans = 0;
while((!pq.empty()) && left){
Edge e = pq.top(); pq.pop();
if(vis[e.to]) continue;
ans += e.len;
left --;
vis[e.to] = true;
for(int i=0; i<graph[e.to].size(); i++){
Edge ee = graph[e.to][i];
if(vis[ee.to] == false){
pq.push(ee);
}
}
}
printf("%d\n",ans);
return 0;
}