一開始題目意思沒理解清楚,以為最小產生樹中因衛星頻道可以刪除的邊的兩點都必須有衛星,這樣S個衛星頻道可以覆蓋幾個點就不確定了,變得很複雜
其實題目意思是將一棵最小產生樹轉化成一個森林,森林裡有S棵樹,每棵樹配一個衛星頻道,並且使得森林裡所有邊中最長的邊的長度最小
其實意思就是可以刪除最小產生樹中的S-1條邊,問剩下的邊中最長的是多少
由於建圖時每兩個點之間都有邊,是稠密圖,故用Prim法比較好
代碼:
#include<iostream><br />#include<algorithm><br />#include<cmath><br />using namespace std;<br />#define inf 0x3f3f3f3f<br />double g[501][501];<br />double e[501],x[501],y[501],dis[501];<br />int s,p,cnt;<br />double cal(double x1,double y1,double x2,double y2)<br />{<br />double x=x1-x2,y=y1-y2;<br />return sqrt(x*x+y*y);<br />}<br />double min(double a,double b)<br />{<br />return a<b?a:b;<br />}<br />void prim()<br />{<br />int i,j,min_node,now;<br />double min_w;<br />for(i=1;i<=p;i++)<br />dis[i]=999999.9;<br />now=1;<br />cnt=0;<br />for(i=1;i<p;i++)<br />{<br />min_w=999999.9;<br />dis[now]=-1;<br />for(j=1;j<=p;j++)<br />{<br />if(j!=now&&dis[j]>=0)<br />{<br />dis[j]=min(dis[j],g[now][j]);<br />if(dis[j]<min_w)<br />{<br />min_w=dis[j];<br />min_node=j;<br />}<br />}<br />}<br />e[cnt++]=min_w;<br />now=min_node;<br />}<br />}<br />int main()<br />{<br />int i,j,test;<br />cin>>test;<br />while(test--)<br />{<br />memset(g,0,sizeof(g));<br />memset(e,0,sizeof(e));<br />cin>>s>>p;<br />for(i=1;i<=p;i++)<br />{<br />cin>>x[i]>>y[i];<br />}<br />for(i=1;i<=p;i++)<br />for(j=i+1;j<=p;j++)<br />{<br />g[i][j]=g[j][i]=cal(x[i],y[i],x[j],y[j]);<br />}<br />prim();<br />sort(e,e+cnt);<br />printf("%.2lf/n",e[p-s-1]);<br />}<br />system("pause");<br />return 0;<br />}