并查集
kruskal算法的应用
需要先将连通的点合并起来,然后再查询。
由于集合的原因,肯定不会包含重复的点。
#include <iostream>
#include <cstdio>
#include <string>
#include <unordered_map>
#include <algorithm>
using namespace std;
const int N = 10007;
struct edge{
int u, v, cost, st;
bool operator < (const edge a)const{
return cost < a.cost;
}
}E[N];
int root[N];
int find(int x){
if(root[x] != x) root[x] = find(root[x]);
return root[x];
}
int main(){
int n;
cin>>n;
for(int i = 1; i <= n; i++){
root[i] = i;
}
int len = n*(n-1)/2;
unordered_map<int, bool> mp;
for(int i = 0; i < len; i++){
cin>>E[i].u>>E[i].v>>E[i].cost>>E[i].st;
if(E[i].st == 1){
int u = find(E[i].u);
int v = find(E[i].v);
if(u != v){
root[v] = u;
}
}
}
sort(E, E+len);
int cost = 0;
for(int i = 0; i < len; i++){ //先连的肯定是花费最小的
int u = find(E[i].u);
int v = find(E[i].v);
if(u != v){
root[v] = u;
cost += E[i].cost;
}
}
cout<<cost<<endl;
return 0;
}