poj 2349(最小生成树应用)
题目链接:http://poj.org/problem?id=2349
思路:由于有S个专门的通道,我们可以先求一次最小生成树,然后对于最小生成树上的边从大到小排序,前S-1条边用S-1个卫星通道连接,那么第S大条边就是我们要找的最小的D了。
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<cmath> 5 #include<algorithm> 6 using namespace std; 7 #define MAXN 555 8 #define inf 1LL<<60 9 10 struct Node{ 11 int x,y; 12 }node[MAXN]; 13 double map[MAXN][MAXN]; 14 double lowcost[MAXN]; 15 double dist[MAXN]; 16 bool mark[MAXN]; 17 int n,m; 18 19 double Cal(int i,int j) 20 { 21 double d1=1.0*(node[i].x-node[j].x)*(node[i].x-node[j].x); 22 double d2=1.0*(node[i].y-node[j].y)*(node[i].y-node[j].y); 23 return sqrt(d1+d2); 24 } 25 26 int cmp(const double &p,const double &q) 27 { 28 return p>q; 29 } 30 31 double Prim(int u0) 32 { 33 int cnt=0; 34 memset(mark,false,sizeof(mark)); 35 for(int i=1;i<=m;i++){ 36 lowcost[i]=map[u0][i]; 37 } 38 lowcost[u0]=0; 39 mark[u0]=true; 40 for(int i=1;i<m;i++){ 41 double MIN=inf; 42 int v=u0; 43 for(int j=1;j<=m;j++){ 44 if(!mark[j]&&lowcost[j]<MIN){ 45 MIN=lowcost[j],v=j; 46 } 47 } 48 if(MIN==inf)break; 49 mark[v]=true; 50 dist[cnt++]=lowcost[v]; 51 for(int k=1;k<=m;k++){ 52 if(!mark[k]&&map[v][k]<lowcost[k]){ 53 lowcost[k]=map[v][k]; 54 } 55 } 56 } 57 sort(dist,dist+cnt,cmp); 58 //for(int i=0;i<cnt;i++)printf("%.2lf\n",dist[i]); 59 return dist[n-1]; 60 } 61 62 63 int main() 64 { 65 int _case,a,b; 66 scanf("%d",&_case); 67 while(_case--){ 68 scanf("%d%d",&n,&m); 69 for(int i=1;i<=m;i++) 70 for(int j=1;j<=m;j++) 71 map[i][j]=map[j][i]=(i==j?0:inf); 72 for(int i=1;i<=m;i++){ 73 scanf("%d%d",&node[i].x,&node[i].y); 74 for(int j=1;j<i;j++){ 75 map[i][j]=map[j][i]=Cal(i,j); 76 } 77 } 78 printf("%.2lf\n",Prim(1)); 79 } 80 return 0; 81 } 82 83 84 85 86