タイトルの説明
州政府の「ブロックされていないプロジェクト」の目標は、州内の任意の2つの村間の道路交通を可能にすることです(ただし、道路を介して間接的に到達できる限り、必ずしも道路で直接接続されている必要はありません)。都市道路の統計表が利用可能になりました。これには、任意の2つの町の間の道路建設のコストと、道路が修復されたかどうかが一覧表示されます。州の円滑な運営に必要な最低限の費用を計算するプログラムを書いてください。
入力
テスト入力にはいくつかのテストケースが含まれています。各テストケースの最初の行は、村の数N(1 <N <100)を示します。次のN(N-1)/ 2行は、村間の道路のコストと建設状況に対応し、各行は4つの正の整数を示します。これらは、2つの村の数(1からNまでの番号)、2つの村間の道路のコスト、および建設の状態です。1は建設済み、0は建設されていないことを意味します。
Nが0の場合、入力は終了します。アウトプット
各テストケースの出力は1行を占め、州の円滑な運用に必要な最小コストが出力されます。
入力例
4 1 2 1 1 1 3 6 0 1 4 2 1 2 3 3 0 2 4 5 0 3 4 4 0 3 1 2 1 1 2 3 2 1 1 3 1 0 0出力例
3 0
クラスカルの最小スパニングツリーの問題は、基本的なブロック解除プロジェクトとは異なります。一部のエッジは既に存在するため、[Find Dad Array]を初期化するときに設定する必要があります代码24-29行
。
【クラスカルアイディア】:重さが一番小さい側を取り出すたびに、リングを形成していない場合はそれを選択し、それ以外の場合は横断を継続する
[判定ループ思考]:配列fがあり、f [n]は点nの祖先を表し、最初の点は独立しているため、それらはすべてそれ自体です。エッジの2つの端点の祖先が同じである場合、このエッジは接続できません。ループが表示されます。
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<iostream>
#include<algorithm>
using namespace std;
const int maxn = 100 + 10;
const int maxn2 = maxn*(maxn-1)/2;
int f[maxn];
struct edge{ // 一条边
int a; // 2端点+1权值+1状态
int b;
int weight;
int status;
}edges[maxn2];
int find(int x){ //找爹
return x==f[x]?x:(find(f[x]));
}
void init(int n,int m){
for(int i=1;i<=n;i++){
f[i]=i;
}
for(int i=0;i<m;i++){
if(edges[i].status==1){ //初始化找爹数组时将已连接的边连接
f[find(edges[i].a)] = find(edges[i].b);
}
}
}
bool cmp(edge e1,edge e2){ //将边数组升序排序
return e1.weight<e2.weight;
}
int main(){
int n;
while(scanf("%d",&n)==1 && n!=0){
int m = n*(n-1)/2;
for(int i=0;i<m;i++){
cin>>edges[i].a>>edges[i].b>>edges[i].weight>>edges[i].status;
}
init(n,m);
sort(edges,edges+m,cmp);
int ans = 0;
for(int i=0;i<m;i++){
if(edges[i].status==1) continue;
int fa = find(edges[i].a); //a的祖先
int fb = find(edges[i].b); //b的祖先
if(fa!=fb){ //不是同一个祖先,相连不会成环
f[fa] = fb; //相连(a的祖先【的祖先】是b的祖先)
ans+=edges[i].weight; //修路加其权值
}
}
cout<<ans<<endl;
}
return 0;
}