某地区经过对城镇交通状况的调查,得到现有城镇间快速道路的统计数据,并提出“畅通工程”的目标:使整个地区任何两个城镇间都可以实现快速交通(但不一定有直接的快速道路相连,只要互相间接通过快速路可达即可)。现得到城镇道路统计表,表中列出了任意两城镇间修建快速路的费用,以及该道路是否已经修通的状态。现请你编写程序,计算出全地区畅通需要的最低成本。
输入格式:
输入的第一行给出村庄数目N (1≤N≤100);随后的N(N−1)/2行对应村庄间道路的成本及修建状态:每行给出4个正整数,分别是两个村庄的编号(从1编号到N),此两村庄间道路的成本,以及修建状态 — 1表示已建,0表示未建。
输出格式:
输出全省畅通需要的最低成本。
输入样例:
4
1 2 1 1
1 3 4 0
1 4 1 1
2 3 3 0
2 4 2 1
3 4 5 0
输出样例:
3
#include<bits/stdc++.h>
using namespace std;
const int Max_Num=110;//定义一个const类型的常数
int n,m;//n用来存放村庄的数量,m用来存放之后输入的一整行的数据行数
int f[Max_Num];//定义一个f数组,用来存放村庄的编号
set<int> st;//set集合,存进去的元素可以自动排序,且每个元素出现有且仅有一次.
struct edge{//定义名为edge的结构体
int u,v,c,f;//u存放起始村庄,v存放终止村庄,c存放道路成本,f存放修建状态
}e[Max_Num*Max_Num];
bool cmp(edge a,edge b){//cmp比较函数
if(a.f==b.f) return a.c<b.c;
return a.f>b.f;
}
void In_it(){
cin>>n;//输入n
m=n*(n-1)/2;//m的值求解得
for(int i=0;i<m;i++){//输入m-1行数据
cin>>e[i].u>>e[i].v>>e[i].c>>e[i].f;
}
sort(e,e+m,cmp);//对结构体进行排序
for(int i=0;i<=n;++i){
f[i]=i;//对每个村庄进行编号,从1-n
}
}
int find_(int x){//查找函数,查找当前x值是否与f[x]相等,不相等则继续调用函数进行寻找
return f[x]==x?x:f[x]=find_(f[x]);
}
void solve(){
int ans=0;//初始化ans为0
for(int i=0;i<m;++i){
int u_=find_(e[i].u),v_=find_(e[i].v);//每次for循环都调用find_函数进行对u_,v_的赋值运算,
//使u_与v_始终是建立了连接的村庄编号
st.insert(e[i].u);st.insert(e[i].v);//将这两个村庄存入集合中
if(e[i].f==1)//如果两个村庄之间存在连接
f[u_]=v_;//那么就让下标为起始村庄编号的数组的值等于终止村庄的标号,表示两村庄已经建立连接
else if(u_!=v_){//两值不等,则需要建立连接
ans+=e[i].c;//ans值更新
f[u_]=v_;//同上
}
if(st.size()==n)break;//当集合中存在了所有的村庄,则跳出循环,for循环不一定完成就可跳出循环
}
cout<<ans<<endl;
}
int main(){
In_it();
solve();
return 0;
}