牛客网题目链接
并查集+kruska算法
版本1
注意:
虽然点只有100个,但是边可能达到5000个,所以数组需要开大点。
统计并查集中的点数,当所有点都包含时可以提前退出。
#include <iostream>
#include <vector>
#include <string>
#include <cmath>
#include <algorithm>
#include <queue>
#include <cstdio>
#include <cctype>
#include <unordered_map>
#include <map>
using namespace std;
const int N = 5005;
typedef pair<int, string> PII;
int root[N];
int find(int x){
if(x != root[x]) root[x] = find(root[x]);
return root[x];
}
struct road{
int u, v, w;
bool operator < (const road a)const{
return w < a.w;
}
}E[N];
int main() {
int n;
while(cin>>n){
if(!n) break;
int m = n*(n-1)/2;
for(int i = 1; i <= n; i++){
root[i] = i;
}
int cnt = 1, w = 0;
for(int i = 0; i < m; i++){
cin>>E[i].u>>E[i].v>>E[i].w;
}
sort(E, E + m);
for(int i = 0; i < m; i++){
int a = find(E[i].u);
int b = find(E[i].v);
if(a != b){
root[b] = a;
w += E[i].w;
cnt++;
}
if(cnt == n) break;
}
cout<<w<<endl;
}
return 0;
}
版本2
以前写的
#include<cstdio>
#include<algorithm>
#define N 5000
using namespace std;
struct edge{
int u,v;
int cost;
}E[N];
bool cmp(edge &a, edge &b){
return a.cost < b.cost;
}
int father[N];
int findFather(int x){
if(x == father[x]) return x;
else{
int tp = findFather(father[x]);
father[x] = tp;
return tp;
}
}
int kruskal(int n){
int path = 0;
for(int i = 1;i <=(n-1)*n/2;i++){
father[i] = i;
}
sort(E+1,E+(n-1)*n/2 +1,cmp);
for(int i = 1;i <= (n-1)*n/2;i++){
int faU = findFather(E[i].u);
int faV = findFather(E[i].v);
if(faU != faV){
father[faU] = faV;
path += E[i].cost;
}
}
return path;
}
int main(){
int n;
while(scanf("%d",&n) != EOF&& n != 0){
for(int i = 1;i <= n*(n-1)/2;i++){
scanf("%d%d%d",&E[i].u,&E[i].v,&E[i].cost);
}
printf("%d\n",kruskal(n));
}
}