hdu 4463 第37届ACM/ICPC杭州赛区K题 最小生成树

题意:给坐标系上的一些点,其中有两个点已经连了一条边,求最小生成树的值

将已连接的两点权值置为0,这样一定能加入最小生成树里

最后的结果加上这两点的距离即为所求

  1 #include<cstdio>
  2 #include<iostream>
  3 #include<algorithm>
  4 #include<cstring>
  5 #include<cmath>
  6 #include<queue>
  7 #include<map>
  8 using namespace std;
  9 #define MOD 1000000007
 10 const int INF=0x3f3f3f3f;
 11 const double eps=1e-5;
 12 #define cl(a) memset(a,0,sizeof(a))
 13 #define ts printf("*****\n");
 14 int n,m,tt;
 15 const int MAXN=110;//最大点数
 16 const int MAXM=10000;//最大边数
 17 int F[MAXN];//并查集使用
 18 struct Edge
 19 {
 20     int u,v;
 21     double w;
 22 }edge[MAXM];//存储边的信息,包括起点/终点/权值
 23 int tol;//边数,加边前赋值为0
 24 void addedge(int u,int v,double w)
 25 {
 26     edge[tol].u=u;
 27     edge[tol].v=v;
 28     edge[tol++].w=w;
 29 }
 30 bool cmp(Edge a,Edge b)
 31 {//排序函数,讲边按照权值从小到大排序
 32     return a.w<b.w;
 33 }
 34 int find(int x)
 35 {
 36     if(F[x]==-1)return x;
 37     else return F[x]=find(F[x]);
 38 }
 39 double Kruskal(int n)//传入点数,返回最小生成树的权值,如果不连通返回-1
 40 {
 41     memset(F,-1,sizeof(F));
 42     sort(edge,edge+tol,cmp);
 43     int cnt=0;//计算加入的边数
 44     double ans=0;
 45     for(int i=0;i<tol;i++)
 46     {
 47         int u=edge[i].u;
 48         int v=edge[i].v;
 49         double w=edge[i].w;
 50         int t1=find(u);
 51         int t2=find(v);
 52         if(t1!=t2)
 53         {
 54             ans+=w;
 55             F[t1]=t2;
 56             cnt++;
 57         }
 58         if(cnt==n-1)break;
 59     }
 60     if(cnt<n-1)return -1;//不连通
 61     else return ans;
 62 }
 63 struct node
 64 {
 65     double x,y;
 66     void in()
 67     {
 68         scanf("%lf%lf",&x,&y);
 69     }
 70 }nn[MAXN];
 71 double dist(node a,node b)
 72 {
 73     return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));
 74 }
 75 int main()
 76 {
 77     int i,j,k;
 78     #ifndef ONLINE_JUDGE
 79     freopen("1.in","r",stdin);
 80     #endif
 81     while(scanf("%d",&n)!=EOF)
 82     {
 83         tol=0;
 84         if(n==0)    break;
 85         int q,p;
 86         scanf("%d%d",&p,&q);
 87         p--,q--;
 88         for(i=0;i<n;i++)
 89         {
 90             nn[i].in();
 91         }
 92         for(i=0;i<n;i++)
 93         {
 94             for(j=i+1;j<n;j++)
 95             {
 96                 addedge(i,j,dist(nn[i],nn[j]));
 97                 if((i==p&&j==q)||(i==q&&j==p))
 98                 {
 99                     addedge(i,j,0);
100                 }
101             }
102         }
103         printf("%.2lf\n",Kruskal(n)+dist(nn[p],nn[q]));
104     }
105 }

 

posted @ 2015-04-19 16:49  miao_a_miao  阅读(200)  评论(0编辑  收藏  举报