标签:
Time Limit: 2000MS | Memory Limit: 65536K | |
Total Submissions: 14977 | Accepted: 4777 |
Description
Input
Output
Sample Input
1 2 4 0 100 0 300 0 600 150 750
Sample Output
212.13
题意及思路:有P个坐标,将P个坐标分为S组,求所有组的生成树的最大边中的最大边。求P个坐标构成的生成树,将边由大到小排序,第S条边即为所求。
#include<cstdio> #include<cmath> #include<cstring> #include<queue> #include<algorithm> #include<vector> using namespace std; const int MAXN=505*505; const double INF=1.0e8; typedef pair<double,int> P; struct Point{ int x,y,index; }points[505]; struct Edge{ int to,next; double cost; }es[MAXN]; int V,E; double dist(int x1,int y1,int x2,int y2) { return sqrt((double)((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2))); } bool comp(double a,double b) { return a > b; } int head[505]; void add_edge(int u,int v,double cost) { es[E].to=v; es[E].cost=cost; es[E].next=head[u]; head[u]=E; E++; } int cnt; double res[505]; double d[505]; int vis[505]; void prim(int s) { for(int i=1;i<=V;i++) { d[i]=INF; vis[i]=0; } d[s]=0; cnt=0; priority_queue<P,vector<P>,greater<P> > que; que.push(P(0,s)); while(!que.empty()) { P now=que.top();que.pop(); int v=now.second; if(vis[v]) continue; res[cnt++]=now.first; vis[v]=1; for(int i=head[v];i!=-1;i=es[i].next) { Edge e=es[i]; if(d[e.to]>e.cost) { d[e.to]=e.cost; que.push(P(d[e.to],e.to)); } } } } int main() { int T; scanf("%d",&T); int S,P; while(T--) { scanf("%d%d",&S,&P); memset(head,-1,sizeof(head)); V=P; E=0; for(int i=0;i<P;i++) { scanf("%d%d",&points[i].x,&points[i].y); points[i].index=i+1; } for(int i=0;i<P;i++) for(int j=i+1;j<P;j++) { int indi=points[i].index; int indj=points[j].index; double co=dist(points[i].x,points[i].y,points[j].x,points[j].y); add_edge(indi,indj,co); add_edge(indj,indi,co); } prim(1); sort(res,res+cnt,comp); printf("%0.2lf\n",res[S-1]); } return 0; }
标签:
原文地址:http://www.cnblogs.com/program-ccc/p/5159069.html