蓝桥杯-PREV22-国王的烦恼-并查集+sort()

蓝桥杯-PREV22-国王的烦恼-并查集

  • 问题描述
      C国由n个小岛组成,为了方便小岛之间联络,C国在小岛间建立了m座大桥,每座大桥连接两座小岛。两个小岛间可能存在多座桥连接。然而,由于海水冲刷,有一些大桥面临着不能使用的危险。
      如果两个小岛间的所有大桥都不能使用,则这两座小岛就不能直接到达了。然而,只要这两座小岛的居民能通过其他的桥或者其他的小岛互相到达,他们就会安然无事。但是,如果前一天两个小岛之间还有方法可以到达,后一天却不能到达了,居民们就会一起抗议。
      现在C国的国王已经知道了每座桥能使用的天数,超过这个天数就不能使用了。现在他想知道居民们会有多少天进行抗议。
  • 输入格式
      输入的第一行包含两个整数n, m,分别表示小岛的个数和桥的数量。
      接下来m行,每行三个整数a, b, t,分别表示该座桥连接a号和b号两个小岛,能使用t天。小岛的编号从1开始递增。
  • 输出格式
      输出一个整数,表示居民们会抗议的天数。
  • 样例输入
    4 4
    1 2 2
    1 3 2
    2 3 1
    3 4 3
  • 样例输出
    2
  • 样例说明
      第一天后2和3之间的桥不能使用,不影响。
      第二天后1和2之间,以及1和3之间的桥不能使用,居民们会抗议。
      第三天后3和4之间的桥不能使用,居民们会抗议。
  • 数据规模和约定
      对于30%的数据,1<=n<=20,1<=m<=100;
      对于50%的数据,1<=n<=500,1<=m<=10000;
      对于100%的数据,1<=n<=10000,1<=m<=100000,1<=a, b<=n, 1<=t<=100000。
      解题思路是参考这里蓝桥杯 历届试题 国王的烦恼(c++)
      
    以下是我参照着以上链接写的,只得90分,现在没有找出问题,后续解决了继续更~
#include<iostream>
#include<algorithm>
using namespace std;
int f[10005];//n个小岛的初始领导
struct node{
	int a;
	int b;
	int t; //天数 
}; //桥的数量 
bool cmp(node x,node y){ //结构体struct的运用,写! 
	return x.t>y.t;
}
int find(int value)  //△ 
{
	int temp1,temp2;
	temp1=value;
	while(value!=f[value])
	{
		value=f[value];
	}
	while(temp1!=value)
	{
		temp2=f[temp1];
		f[temp1]=value;
		temp1=temp2;
	}
	return value;
}
int research(int p,int q){
	p=find(p);
	q=find(q);
	if(p!=q){
		f[p]=q;
		return 1;
	}
	else
	    return 0;
}
int main(){
	int n,m;
	cin>>n>>m;
	node no[m];
	for(int i=1;i<=n;i++){
		f[i]=i;
	}
	for(int i=1;i<=m;i++){
		cin>>no[i].a>>no[i].b>>no[i].t;//结构体的表达! 
	}
	sort(no,no+m,cmp);//天数从大到小排序 
	int ans=0;//烦恼的天数
	int pre=-1; 
	for(int i=1;i<=m;i++)
    {
    	if(research(no[i].a,no[i].b)==1&&no[i].t!=pre)
    	{
    		ans++;
    		pre=no[i].t;
    	}
    }
    cout<<ans;
	return 0;
}

嗯呢呢呢呢~试了好多遍,找到问题了!
sort()函数!
sort(A,A+n,cmp);
此函数有3个参数:
参数1:第一个参数是数组的首地址,一般写上数组名就可以,因为数组名是一个指针常量。
参数2:第二个参数相对较好理解,即首地址加上数组的长度n(代表尾地址的下一地址)。
参数3:默认可以不填,如果不填sort会默认按数组升序排序。也就是1,2,3,4排序。也可以自定义一个排序函数,改排序方式为降序什么的,也就是4,3,2,1这样。

改正之后,正确的的代码。

#include<iostream>
#include<algorithm>
using namespace std;
int f[10005];//n个小岛的初始领导
struct node{
	int a;
	int b;
	int t; //天数 
}; //桥的数量 
bool cmp(node x,node y){ //结构体struct的运用,写! 
	return x.t>y.t;
}
int find(int value)  //△ 
{
	int temp1,temp2;
	temp1=value;
	while(value!=f[value])
	{
		value=f[value];
	}
	while(temp1!=value)
	{
		temp2=f[temp1];
		f[temp1]=value;
		temp1=temp2;
	}
	return value;
}
int research(int a,int b){
	a=find(a);
	b=find(b);
	if(a!=b){
		f[a]=b;
		return 1;
	}
	else
	    return 0;
}
int main(){
	int n,m;
	cin>>n>>m;
	node no[m];
	for(int i=1;i<=n;i++){
		f[i]=i;
	}
	for(int i=0;i<m;i++){
		cin>>no[i].a>>no[i].b>>no[i].t;//结构体的表达! 
	}
	sort(no,no+m,cmp);//天数从大到小排序 
	int ans=0;//烦恼的天数
	int pre=-1; 
	for(int i=0;i<m;i++)
    {
    	if(research(no[i].a,no[i].b)==1&&no[i].t!=pre)
    	{
    		ans++;
    		pre=no[i].t;
    	}
    }
    cout<<ans;
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值