【牛客网】KY118 继续畅通工程
作者:互联网
这道题可以使用并查集解决,利用Kruskal算法的思想构建最小生成树,其中,我使用优先队列根据修建状态进行排序,优先已建的路:
#include<iostream>
#include<string>
#include<queue>
using namespace std;
const int N = 100 + 10;
int arr[N];
struct Distance{
int n1, n2, dis, state;
Distance(int n1, int n2, int d, int s): n1(n1), n2(n2), dis(d), state(s){}
bool operator>(Distance d) const{
if(state == d.state) return dis > d.dis;
return state < d.state;
}
};
void Initial(int *arr, int n){
for(int i = 1; i <= n; i++) arr[i] = -1;
}
int Find(int *arr, int x){
int root = x;
while(arr[root] > 0) root = arr[root];
while(x != root){
int t = arr[x];
arr[x] = root;
x = t;
}
return root;
}
bool Union(int *arr, int x, int y){
int root1 = Find(arr, x);
int root2 = Find(arr, y);
if(root1 != root2){
if(arr[root2] > arr[root1]){
arr[root1] += arr[root2];
arr[root2] = root1;
}else{
arr[root2] += arr[root1];
arr[root1] = root2;
}
return true;
}
return false;
}
int main(){
int n, a, b, dis, state;
while(scanf("%d", &n) != EOF){
if(n == 0) break;
int len = (n - 1) * n / 2;
priority_queue<Distance, vector<Distance>, greater<Distance>> pq;
Initial(arr, n);
for(int i = 0; i < len; i++){
scanf("%d%d%d%d", &a, &b, &dis, &state);
pq.push(Distance(a, b, dis, state));
}
len = pq.size();
int sum = 0;
for(int i = 0; i < len; i++){
Distance d = pq.top();
pq.pop();
if(Union(arr, d.n1, d.n2)){
if(!d.state) sum += d.dis;
}
}
printf("%d\n", sum);
}
return 0;
}
标签:arr,int,牛客,state,KY118,畅通,root2,root1,dis 来源: https://blog.csdn.net/weixin_55267022/article/details/122799525