算法作业3:畅通工程问题

某地区经过对城镇交通状况的调查,得到现有城镇间快速道路的统计数据,并提出“畅通工程”的目标:使整个地区任何两个城镇间都可以实现快速交通(但不一定有直接的快速道路相连,只要互相间接通过快速路可达即可)。现得到城镇道路统计表,表中列出了任意两城镇间修建快速路的费用,以及该道路是否已经修通的状态。现请你编写程序,计算出全地区畅通需要的最低成本。

输入格式:

输入的第一行给出村庄数目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;
}

 

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值