利用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
*/