[蓝桥杯练习]聪明的猴子

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

利用MST的性质:MST的每个边权都是尽可能地最小,以组合起连接所有的结点,即可以用最小的花费遍历整个图且遍历路径不会出现环路

KRUSKAL

#include <bits/stdc++.h>
using namespace std;
int able[5005];
int x[5005],y[5005];//存储i点的x与y坐标 
int bcj[5005];//并查集 
struct Edge{//边 
    int v1,v2; 
    double w;
}edge[1000005];
int cmp(Edge a, Edge b){return a.w < b.w;}
int find(int x){//并查集查找 
    if(bcj[x]!=x)bcj[x]=find(bcj[x]);//带路径压缩
    return bcj[x];
}
void merge(int v1,int v2){//并查集合并 
    v1=find(v1);v2=find(v2);
    bcj[v2]=v1;
}
int main(){
	//
    int nums;cin>>nums;
    for(int i=1;i<=nums;++i)cin>>able[i];
    //
    int n;cin>>n;
    for(int i=1;i<=n;++i)bcj[i]=i;//并查集初始化
    //
    for(int i=1;i<=n;i++)cin>>x[i]>>y[i];//读取结点x坐标y坐标 
    int cnt=0;
    for(int v1=1;v1<=n;++v1)for(int v2=v1+1;v2<=n;++v2){//求出任意两点的权重 
        double w=sqrt(pow((x[v1]-x[v2]),2)+pow((y[v1]-y[v2]),2));//v1的x坐标减去v2的x坐标... 
        edge[++cnt]={v1,v2,w};
    }
    sort(edge+1,edge+cnt+1,cmp);
    int MSTm = 0;
    double maxw = 0.0;
    for(int i=1;i<=cnt;++i){
        if(find(edge[i].v1)!=find(edge[i].v2)){
            merge(edge[i].v1,edge[i].v2);
            ++MSTm;
            maxw=max(maxw,edge[i].w);//获取MST中最大的边 
        }
        if(MSTm==n-1)break;//n-1条边就可以构造MST 
    }
  	int ans=0;
    for(int i=1;i<=nums;++i)if(able[i]>=maxw)ans++;
    cout<<ans<<endl;
    return 0;
}

错误代码

利用FLOYD更新所有点对间的最短路径,但这个代码有误

代码有误
#include<bits/stdc++.h>
using namespace std;
const int N = 1005; 
struct dian{
	int x,y;
};
vector<dian>node(N);

int g[N][N];
int main(){
	ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
	fill(g[0],g[0]+N*N,1001);
	int nums;cin>>nums;int able[nums]; 
	for(int i=1;i<=nums;++i)cin>>able[i];
	int n;cin>>n;int inx,iny;
	for(int i=1;i<=n;++i){
		cin>>inx>>iny;
		node[i].x=inx; node[i].y=iny;
	} 
	for(int v1=1;v1<=n;++v1)for(int v2=v1+1;v2<=n;v2++){
		g[v1][v2]=g[v2][v1]=ceil(sqrt(pow(double(node[v1].x-node[v2].x),2)+pow(double(node[v1].y-node[v2].y),2)));
	}
//	for(int v1=1;v1<=n;++v1){
//		for(int v2=1;v2<=n;v2++){
//			cout<<setw(5)<<g[v1][v2]<<" ";
//		}cout<<endl;
//	}
	vector<int>exam;
	for(int i=2;i<=n;++i){
		int minn=INT_MAX;
		for(int j=1;j<=i-1;++j){
			minn=min(g[j][i],minn);
//			cout<<g[j][i]<<" ";
		}
//		cout<<endl;
		if(minn!=INT_MAX)exam.push_back(minn);
	}
//	for(int i=0;i<exam.size();++i)cout<<exam[i]<<" ";
	int maxx = *max_element(exam.begin(),exam.end());
	sort(able,able+nums);
	for(int i=0;i<nums;++i){
		if(able[i]>=maxx)return !(cout<<nums-i);
	}
	return 0;
}
/*
4
 1 2 3 4
6
0 0
1 0
1 2
-1 -1
-2 0
2 2
*/ 
  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值