题意:给出一个n和一个n*(n-1)/2条无向边,求MST
题解:prime邻接矩阵也可以,这里是为了写一波邻接表
代码如下:
#include<iostream>
#include<cstring>
#include<string>
#include<cstdio>
#include<cmath>
#include<vector>
#include<queue>
#include<map>
#include<algorithm>
using namespace std;
#define ll long long
#define inf 0x3f3f3f3f
const int maxn = 1e3;
struct prim
{
struct nodes
{
int v, w;
nodes(int vv, int ww) :v(vv), w(ww) {}
bool operator <(const nodes &a)const
{
return w > a.w;
}
};
vector<nodes>edge[maxn];
bool vis[maxn];
int n, ans;
void init()//清空
{
for (int i = 0; i <= n; i++)
{
edge[i].clear();
vis[i] = 0;
}
}
void add(int u, int v, int w) //添加无向边
{
edge[u].push_back(nodes(v, w));
edge[v].push_back(nodes(u, w));
}
void solve()
{
priority_queue<nodes>que;
for (int i = 0; i < edge[1].size(); i++)
que.push(edge[1][i]); //将起点的所有连接边全部加入队列中来
vis[1] = 1, ans = 0;
int cnt = n - 1;
while (cnt--) //添加n-1个点入集合
{
nodes e = que.top();
que.pop();
if (vis[e.v])
while (vis[e.v])
{
e = que.top();
que.pop();
}
ans += e.w, vis[e.v] = 1; //加入生成树的该点将被标记访问
for (int i = 0; i < edge[e.v].size(); i++)
if (!vis[edge[e.v][i].v])//当前加入生成树的点可扩充出的边指向的节点
que.push(edge[e.v][i]);//如果没有被访问才会加入到队列当中来
}
}
}pri;
void input()
{
int uu, vv, ww;
for (int i = 0; i < pri.n*(pri.n - 1) / 2; i++)
{
scanf("%d%d%d", &uu, &vv, &ww);
pri.add(uu, vv, ww);
}
}
int main()
{
while (~scanf("%d", &pri.n) && pri.n)
{
pri.init();
input();
pri.solve();
cout << pri.ans << endl;
}
return 0;
}