poj 2349 Arctic Network

题目链接:http://poj.org/problem?id=2349

先求出每两个顶点之间的距离,(注意:是double类型的),然后用普里姆算法(Prim)求最小生成树。由于无线电的数目已给出m,所以需要把最小生成树分成m份,即删除m-1条边,得到m个连通分量。关键是删除哪些边呢,题目要求最小的D,故把构成最小生成树的边从大到小排序,删除前m-1条边,第m条边即所要求的最小D。

#include<iostream> #include<cstdio> #include<algorithm> #include<cstring> #include<queue> #include<stack> #include<cmath> using namespace std; #define INF 0x3f3f3f3f #define maxn 2100 int N,M; double a[maxn][maxn]; int v[maxn]; double ans[maxn]; double dis[maxn]; int k; struct point { int x,y; }p[maxn]; double dit(int i,int j) { return sqrt((p[i].x-p[j].x)*(p[i].x-p[j].x)+(p[i].y-p[j].y)*(p[i].y-p[j].y)); } void prim(int s) { for(int i=2;i<=M;i++) dis[i] = a[s][i]; dis[s] = 0; v[s] = 1; int index; for(int i=1;i<M;i++) { double Min = INF; for(int j=1;j<=M;j++) { if(!v[j]&&dis[j]<Min) { Min = dis[j]; index = j; } } ans[k++] = Min; v[index] = 1; for(int j=1;j<=M;j++) { if(dis[j]>a[index][j]) dis[j] = a[index][j]; } } } int main() { int t; scanf("%d",&t); while(t--) { k = 0; memset(ans,0,sizeof(ans)); memset(v,0,sizeof(v)); scanf("%d%d",&N,&M); for(int i=1; i<=M; i++) scanf("%d%d",&p[i].x,&p[i].y); for(int i=1;i<M;i++) for(int j=i;j<=M;j++) { if(i == j) a[i][j] = INF; else a[i][j] = a[j][i] = dit(i,j); } prim(1); sort(ans,ans+M); printf("%.2f\n",ans[M-N]); } return 0; }

 

posted @ 2016-08-02 10:27  biu~biu~biu~  阅读(171)  评论(0编辑  收藏  举报