#include <algorithm>
#include <iostream>
using namespace std;
const int N = 110;
int n,m,p[N];
struct edge{
int a,b,w;
};
int find(int x){
if(p[x]!=x) p[x]=find(p[x]);
return p[x];
}
bool cmp(edge a,edge b){ //按照w升序排序
return a.w<b.w;
}
int main() {
while (cin >> n) {
if(n==0)break;
m=n*(n-1)/2;
edge edges[m];
for(int i=0;i<m;i++){
int a,b,w,flag;
cin>>a>>b>>w>>flag;
if(flag==0) edges[i]={a,b,w};
else edges[i]={a,b,0};
}
//初始化并查集每个节点 1~n
for(int i=1;i<=n;i++) p[i]=i;
//把边升序排序
sort(edges, edges+m,cmp);
//Kruskal算法
int res = 0,cnt=0;
for(int i=0;i<m;i++){
edge e = edges[i];
int p1 = find(e.a);
int p2 = find(e.b);
if(p1!=p2){
res+=e.w;
cnt++;
p[p1]=p2;
}
}
if(cnt<n-1) ;
else cout<<res<<endl;
}
}
// 64 位输出请用 printf("%lld")
【算法思路】:
- 并查集+Kruskal最小生成树算法;
- 若路已经修好,则就把他的权值设为0;

京公网安备 11010502036488号