最小生成树 | ||
---|---|---|
Time Limit: 2000 MS | Memory 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 MS | Memory 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;
}