HDU 4463 Outlets 最小生成树

来源:互联网 发布:象棋小鹤求败是软件 编辑:程序博客网 时间:2024/06/05 11:38

题意:给出n个坐标,求出最短的路径使这n个点相连。其中有两个点必须连。

思路:裸的最小生成树。需要注意的就是对这两个点特殊处理。

          如果用prim的话,需要将所有与这两个点相连的边加入。如果是krusal就没有什么吧。。

(好久没有打了。。手残了好几发)

代码如下:

#include <cstdio>#include <algorithm>#include <cstring>#include <cmath>#include <utility>#include <queue>using namespace std;typedef pair<double,int> pdi;const int MAX = 55;double x[MAX];double y[MAX];double d[MAX][MAX];bool used[MAX];int p,q;priority_queue<pdi> pq;int main(void){    //freopen("input.txt","r",stdin);    int N;    while(scanf("%d",&N), N){        scanf("%d %d",&p,&q);        for(int i = 1; i <= N; ++i)            scanf("%lf %lf", &x[i], &y[i]);        for(int i = 1; i <= N; ++i){            for(int j = 1; j <= i; ++j)                d[i][j] = d[j][i] = sqrt((x[i] - x[j]) * (x[i] - x[j]) + (y[i] - y[j]) * (y[i] - y[j]));        }        double ans = d[p][q];        memset(used,0,sizeof(used));        used[p] = used[q] = true;        for(int i = 1; i <= N; ++i){            pq.push(pdi(-d[p][i],i));            //pq.push(pdi(-d[q][i],i));        }        while(!pq.empty()){            pdi info = pq.top();pq.pop();            double di = -info.first;            int u = info.second;            if(used[u]) continue;            //printf("%.2f %d\n",di,u);            used[u] = true;            ans += di;            for(int i = 1; i <= N; ++i)                if(!used[i])                    pq.push(pdi(-d[u][i],i));        }        printf("%.2f\n",ans);    }    return 0;}

0 0