POJ 2349 Arctic Network(最小生成樹+第K大的邊)
阿新 • • 發佈:2018-12-11
題意:有S顆衛星和P個哨所,有衛星的兩個哨所之間可以任意通訊;否則,一個哨所只能和距離它小於等於D的哨所通訊。給出衛星的數量和P個哨所的座標,求D的最小值。
思路:因為題目要求每兩個點都能通訊,所以可以轉化成最小生成樹,然後記錄每次加進去的邊,最後對這個陣列排一下序,因為s個衛星能連s-1條邊,所以取rec[p-2-(s-1)]即rec[p-s-1]就是滿足條件的D。
#include<cstdio> #include<cstring> #include<algorithm> #include<iostream> #include<string> #include<vector> #include<stack> #include<bitset> #include<cstdlib> #include<cmath> #include<set> #include<list> #include<deque> #include<map> #include<queue> #include<iomanip> using namespace std; #define inf 0x3f3f3f3f #define ll long long const int maxn=505; const double eps=1e-8; const double PI = acos(-1.0); ll gcd(ll a,ll b) { return b==0?a:gcd(b,a%b); } bool vis[maxn]; double lowc[maxn],rec[maxn]; double prim(double cost[][maxn],int n) { int ans=0; memset(vis,false,sizeof(vis)); memset(rec,0,sizeof(rec)); vis[0]=true; for(int i=1; i<n; i++) { lowc[i]=cost[0][i]; } for(int i=0; i<n-1; i++) { double minc=inf; int p=-1; for(int j=0; j<n; j++) { if(!vis[j]&&minc>lowc[j]) { minc=lowc[j]; p=j; } } if(minc==inf) return -1; ans+=minc; rec[i]=minc; vis[p]=true; for(int j=0; j<n; j++) { if(!vis[j]&&lowc[j]>cost[p][j]) lowc[j]=cost[p][j]; } } return ans; } struct node { double x,y; }; double dis(node a,node b) { return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y)); } int main() { std::ios::sync_with_stdio(false); std::cin.tie(0); std::cout.tie(0); int t; cin>>t; while(t--) { node a[maxn]; int s,p; double g[maxn][maxn]; cin>>s>>p; for(int i=0;i<p;++i) { cin>>a[i].x>>a[i].y; } for(int i=0;i<p;i++) { for(int j=i+1;j<p;j++) { g[i][j]=g[j][i]=dis(a[i],a[j]); } } prim(g,p); sort(rec,rec+p-1); // cout<<p-s-1<<endl; printf("%.2lf\n",rec[p-s-1]); } return 0; }