给你n个点的哨点坐标,然后对应有M个卫星,问怎样连接使通信花费最小,给出最小花费的最长边
将拥有卫星的两个哨所可以直接连接,不需要花费
思路:由于要求出最小花费的最长边,所以我们去掉M-1条最大边,即输出第 N-M条边即为所求
要找到连接的第N-M边,我们就利用kruskal算法来求解
完整代码:(关于精度的输出,还是要注意G++用%f,c++用%lf)
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #include<cmath> using namespace std; const int maxn=1e4;//点数 const int maxm=1e6+10;//边数 int pre[maxn]; struct Edge{ int u,v; double w; }edge[maxm]; int top; int cnt; double ans; int n,m; struct Spot{ double x,y; }spot[maxn]; void addedge(int u,int v,double w){ edge[top].u=u; edge[top].v=v; edge[top++].w= w ; } bool cmp(Edge a,Edge b) { return a.w<b.w; } int find(int x) { if(x!=pre[x]) return pre[x] = find(pre[x]); else return pre[x]; } bool unite(int x,int y){ int fx = find(x); int fy = find(y); if(fx!=fy) { pre[fx] = fy; cnt++; return true; } else return false; } double kruskal(){ sort(edge,edge+top,cmp);//一次性把所有的边都排了 int u,v; double w; for(int i=0;i<top;i++){ u=edge[i].u; v=edge[i].v; w=edge[i].w; unite(u,v); if(cnt == n-m) { ans = w; break; } } if(cnt<n-m) return -1; return ans; } void init(int n){ memset(edge,0,sizeof(edge)); for(int i=0;i<=n;i++) pre[i] = i; ans = top = cnt = 0; } double getDist(int i,int j){ double sX = (spot[i].x-spot[j].x)*(spot[i].x-spot[j].x); double sY = (spot[i].y-spot[j].y)*(spot[i].y-spot[j].y); double dis = sqrt(sX+sY); return dis; } int main(){ int T; cin>>T; int w,a,b; while(T--){ cin>>m>>n; init(n); top=cnt=0; for(int i=0; i<n;i++){ cin>>spot[i].x>>spot[i].y; } for(int i=0;i<n;i++){ for(int j=i+1;j<n;j++){ double cost = getDist(i,j); addedge(i,j,cost); addedge(j,i,cost); } } printf("%.2f\n",kruskal()); } return 0; }