HDU - 1233 还是畅通工程 (prime-邻接表)

题目链接

题意:给出一个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;
}


猜你喜欢

转载自blog.csdn.net/weixin_41156591/article/details/81837723
今日推荐