C++最小生成树

最小生成树
Time Limit: 2000 MSMemory Limit: 1000 KB

Description

给出一个无向网,求该无向网的最小生成树。各条边的权重不超过100000。

Input

输入的第一行是一个int型整数T,表示一个有T组数据。
每组数据第一行包含两个数n,m。n表示该网的顶点个数,3 ≤ N ≤ 100,m 表示无向边的个数。
接下来有m行,每行三个数,ai,bi,ci,表示点ai到点bi有一条权重为ci的边。

Output

输出该最小生成树的权重。保证最小生成树存在。

Sample Input

1
4 5
1 2 4
1 3 9
2 3 8
4 3 16
2 4 17

Sample Output

28

结果代码:

#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
struct Edge
{
	Edge(int i, int j, int k)
	{
		a = i;
		b = j;
		v = k;
	}
	int a; int b; int v;
};
class Mycompare
{
public:
	bool operator()(Edge& n1, Edge& n2)
	{
		return n1.v < n2.v;
	}
};

int main()
{
	int T = 0;
	cin >> T;
	for (int t = 0; t < T; t++)
	{
		int n, m;
		cin >> n;
		cin >> m;
		int* arr = new int[n];
		for (int i = 0; i < n; i++)
			arr[i] = 0;
		vector<Edge>all;
        int a = 0; int b = 0; int c = 0;
	    for(int i=0;i<m;i++)
		{
			cin >> a; cin >> b; cin >> c;
			Edge temp(a, b, c);
			all.push_back(temp);

		}
		sort(all.begin(), all.end(), Mycompare());
		int count = 0; int sum = 0;
		for (vector<Edge>::iterator it = all.begin(); it != all.end(); it++)
		{
			if (arr[it->a] == 0 && arr[it->b] == 0)
			{
				sum += it->v;
				if(it->a< it->b)
				{ 
				arr[it->a] = it->a;
				arr[it->b] = it->a;
				}
				else
				{
					arr[it->a] = it->b;
					arr[it->b] = it->b;
				}
                count++;
			}
			else if ((arr[it->a] != 0 && arr[it->b] == 0) || (arr[it->a] == 0 && arr[it->b] != 0))
			{
				sum += it->v;
				if (arr[it->a] != 0)
				{
				
					arr[it->b] = arr[it->a];
				}
				else
				{
					arr[it->a] = arr[it->b];
					
				}
                count++;
            }
			else if (arr[it->a] != 0 && arr[it->b] != arr[it->a] )
			{
				sum += it->v;
				int p = arr[it->a]; int q = arr[it->b];
				if (p < q)
				{
					for (int i = q; i < n; i++)
						if (arr[i] ==q)arr[i] = p;
                }
				else
					for (int i = p; i < n; i++)
						if (arr[i] == p)arr[i] = q;
				count++;
			}
			if (count == n - 1)break;
		}
		cout << sum << endl;
		delete[]arr;
	}
	return 0;
}

SEUOJ1029

最小生成树
Time Limit: 2000 MSMemory Limit: 5000 KB

Description

给定n(n<=500)个顶点,以及E(E<=20000)条边,计算最小生成树的权值.

Input

第一行输入T表示有T组数据。每组数据第一行输入n、E,分别表示顶点数和边数. 接下来
输入E行每行三个正整数u(1<=u<=n)、v(1<=v<=n)、w,表示顶点u到顶点v之间无向边
长度w(可能有重边)。

Output

输出T行正整数,第i行表示第i组数据的最小生成树权值, 若不能构建最小生成树输出-1。

Sample Input

3
2 2
1 2 1
1 2 2
3 1
2 3 1
3 3
1 2 2
1 2 3
2 3 1

Sample Output

1
-1
3
#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
struct Edge
{
	Edge(int i, int j, int k)
	{
		a = i;
		b = j;
		v = k;
	}
	int a; int b; int v;
};
class Mycompare
{
public:
	bool operator()(Edge& n1, Edge& n2)
	{
		return n1.v < n2.v;
	}
};

int main()
{
	int T = 0;
	cin >> T;
	while(T--)
	{
		int n, m;
		cin >> n;
		cin >> m;
		int* arr = new int[n+1];
		bool* vist = new bool[n+1];
		for (int i = 1; i < n+1; i++)
			arr[i] = 0;
		for (int i = 1; i < n+1; i++)
			vist[i] = 0;
		vector<Edge>all;
		int a = 0; int b = 0; int c = 0;
		for (int i = 0; i < m; i++)
		{
			cin >> a; cin >> b; cin >> c;
			Edge temp(a, b, c);
			all.push_back(temp);
			vist[a] = true;
			vist[b] = true;

		}
		int tag = 0;
		for (int i = 1; i <= n; i++)
		{
			tag += vist[i];

		}
		if(tag!=n) { cout << -1 << endl; continue; }
		sort(all.begin(), all.end(), Mycompare());
		int count = 0; int sum = 0;
		for (vector<Edge>::iterator it = all.begin(); it != all.end(); it++)
		{
			if (arr[it->a] == 0 && arr[it->b] == 0)
			{
				sum += it->v;
				if (it->a < it->b)
				{
					arr[it->a] = it->a;
					arr[it->b] = it->a;
				}
				else
				{
					arr[it->a] = it->b;
					arr[it->b] = it->b;
				}
				count++;
			}
			else if ((arr[it->a] != 0 && arr[it->b] == 0) || (arr[it->a] == 0 && arr[it->b] != 0))
			{
				sum += it->v;
				if (arr[it->a] != 0)
				{

					arr[it->b] = arr[it->a];
				}
				else
				{
					arr[it->a] = arr[it->b];

				}
				count++;
			}
			else if (arr[it->a] != 0 && arr[it->b] != arr[it->a])
			{
				sum += it->v;
				int p = arr[it->a]; int q = arr[it->b];
				if (p < q)
				{
					for (int i = 1; i <=n; i++)
						if (arr[i] == q)arr[i] = p;
				}
				else
					for (int i = 1; i <=n; i++)
						if (arr[i] == p)arr[i] = q;
				count++;
			}
			if (count == n - 1)break;
		}
		cout << sum << endl;
		delete[]arr;
		delete[]vist;
	}
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

convK

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值