时间复杂度O(mlogn)
计算带权无向连通图G的最小生成树。
输入格式:
第一行两个整数:N(1≤N≤300000),表示结点集{1,2,3,⋯,N};M(0≤M≤600000)表示边的条数。
接下来M行,每行表示一条带权的边,用3个整数u,v,c表示,分别表示一条边的两个端点以及其权值(权值范围0≤c≤10
9
)。
输出格式:
一个整数,表示G的最小生成树的边权之和。
#include
#include
#include
#include
using namespace std;
const int N=1000;
const int INF = 0x3f3f3f3f;
struct node
{
int to;
int v;
node(int n, int o) :to(n), v(o){};
};
struct cmp
{
bool operator()(node a, node b)
{
return a.v > b.v;
}
};
vectorvec[N];
int dis[N];
int vis[N];
int n, m;
void Prim(int x)//x作为起点可以随便找
{
priority_queue<node, vector, cmp>que;
memset(dis,INF,N);
memset(vis, 0, N);
dis[x] = 0;
que.push(node(x, 0));
while(!que.empty())
{
node t = que.top();
que.pop();
int qq = t.to;
if (vis[qq] == 1)
{
continue;
}
vis[qq] = 1;
for (int i = 0; i < vec[qq].size(); i++)
{
node tt = vec[qq][i];
if (vis[tt.to] != 1 && dis[tt.to] > tt.v)
{
dis[tt.to] = tt.v;
que.push(node(tt.to, dis[tt.to]));
}
}
}
int sum = 0;
for (int i = 1; i <= n; i++)
{
sum = sum + dis[i];
}
cout << sum << endl;
}
int main()
{
cin >> n >> m;
for (int i = 1; i <=n; i++)
{
vec[i].clear();
}
for (int i = 0; i < m; i++)
{
int a, b, c;
cin >> a >> b >> c;
vec[a].push_back(node(b, c));
vec[b].push_back(node(a, c));
}
Prim(1);
}
此代码仅作参考,因为输入方式与大多数题目不一样我在此附加上测试数据
5 10
1 2 3
1 3 7
1 4 9
1 5 5
2 3 6
2 4 8
2 5 4
3 4 9
3 5 7
4 5 2