这个题貌似是12年杭州亚洲赛的题==,题意是求一个最小生成树,但是要求有两个已知点必须直接连着==其实挺水的,prim不好实现 改了一晚上。。。还是不知道自己最开始为啥错了=。=
Description
Input
Output
Sample Input
4 2 3 0 0 1 0 0 -1 1 -1 0
Sample Output
3.41
#include<iostream> #include<cstring> #include<cstdio> #include<cmath> #include<algorithm> using namespace std; const int maxn=60*60; struct point { int x,y; double dis; point(){} point(int _x,int _y,double _d):x(_x),y(_y),dis(_d){} bool operator <(const struct point &tmp)const{ return this->dis<tmp.dis; } }p[maxn]; point pp[100]; int par[60]; void init(){ for(int i=0;i<60;i++) par[i]=i; } int find_par(int x){ if(x!=par[x]) return par[x]=find_par(par[x]); return par[x]; } bool Union(int x,int y){ x=find_par(x); y=find_par(y); if(x!=y){ par[y]=x; return true; } return false; } double calu(point a,point b){ return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y)); } int main() { // freopen("cin.txt","r",stdin); int n,p1,q1; while(~scanf("%d",&n)&&n) { init(); scanf("%d%d",&p1,&q1); int cnt=0; for(int i=1;i<=n;i++) { int x,y; scanf("%d%d",&pp[i].x,&pp[i].y); for(int j=1;j<i;j++) { double d=calu(pp[i],pp[j]); p[cnt++]=point(i,j,d); } } double ans=0; Union(p1,q1); ans+=calu(pp[p1],pp[q1]); sort(p,p+cnt); for(int i=0;i<cnt;i++) { if(Union(p[i].x,p[i].y)) ans+=p[i].dis; } printf("%.2lf\n",ans); } }