(最小生成樹+技巧)POJ 3625 - Building Roads

題意:ios

平面上有不少點,有些點已經連了起來,如今想讓你再連點,使得全部點連通,而且使新鏈接總距離最小。spa

 

分析:code

顯然最小生成樹,可是不知道怎麼處理已經連好的邊。blog

看了別人的代碼,纔想到,直接把已經連好的邊的花費賦爲0不就好了。string

由於你只須要弄出最小生成樹,而已經在新增邊的時候讓已經連好的邊優先選。it

 

代碼:io

 

 1 #include <cstdio>
 2 #include <cstring>
 3 #include <algorithm>
 4 #include <vector>
 5 #include <cmath>
 6 #include <iostream>
 7 
 8 using namespace std;
 9 
10 const int inf=0x3f3f3f3f;
11 const int maxn=1010;
12 
13 double x[maxn],y[maxn];
14 double cost[maxn][maxn];
15 double lowcost[maxn];
16 bool vis[maxn];
17 
18 
19 
20 double  dis(double x1,double y1,double x2,double y2) {
21     return sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2));
22 }
23 
24 int n,m;
25 
26 int main() {
27 
28     while(~scanf("%d%d",&n,&m)) {
29         for(int i=0; i<n; i++) {
30             scanf("%lf%lf",&x[i],&y[i]);
31         }
32         for(int i=0; i<n; i++) {
33             for(int j=0; j<n; j++) {
34                 cost[i][j]=dis(x[i],y[i],x[j],y[j]);
35             }
36         }
37         for(int i=0; i<m; i++) {
38             int u,v;
39             scanf("%d%d",&u,&v);
40             u--,v--;
41             cost[u][v]=cost[v][u]=0;
42         }
43         memset(vis,false,sizeof(vis));
44         for(int i=1; i<n; i++)lowcost[i]=cost[0][i];
45         vis[0]=true;
46         double ans=0;
47         for(int i=1; i<n; i++) {
48             double minc = 1000000000.0;
49             int p=-1;
50             for(int j=0; j<n; j++) {
51                 if(!vis[j]&&lowcost[j]<minc) {
52                     minc=lowcost[j],p=j;
53                 }
54             }
55             ans+=minc;
56             vis[p]=true;
57             for(int j=0; j<n; j++) {
58                 if(!vis[j]&&lowcost[j]>cost[p][j]) {
59                     lowcost[j]=cost[p][j];
60                 }
61             }
62         }
63         printf("%.2f\n",ans);
64     }
65 
66     return 0;
67 
68 }
相關文章
相關標籤/搜索