zoukankan      html  css  js  c++  java
  • UvaLive 4872 Underground Cables (最小生成树)

    题意:

    就是裸的最小生成树(MST), 完全图, 边长是实数。

    分析:

    算是复习一下MST把

    方法一: prim 复杂度(n^2)

     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 const int maxn = 1e3 + 7;
     4 const int inf = 0x3f3f3f3f;
     5 double G[maxn][maxn], dis[maxn];
     6 bool vis[maxn];
     7 int x[maxn], y[maxn];
     8 int N;
     9 double p2pdis(int x1, int y1, int x2, int y2){
    10     double dis = sqrt((x1-x2) * (x1 - x2) + (y1-y2) * (y1-y2));
    11     return dis;
    12 }
    13 int main(){
    14     #if LOCAL
    15     freopen("1.txt","r",stdin);
    16     #endif // LOCAL
    17 
    18     while(scanf("%d", &N) && N){
    19         memset(G,0,sizeof(G));
    20         memset(vis,0,sizeof(vis));
    21         for(int i = 0; i < N; i++){
    22             scanf("%d %d", &x[i], &y[i]);
    23         }
    24 
    25         for(int i = 0; i < N; i++){
    26             for(int j = 0; j < N; j++){
    27                 if(j != i){
    28                     G[i][j] = p2pdis(x[i],y[i],x[j],y[j]);
    29                 }
    30             }
    31         }
    32         
    33         double ans = 0;
    34         
    35         vis[0] = 1;
    36         for(int i = 0; i < N; i++){
    37             dis[i] = G[0][i]; //一开始起点加入树中, 所以可以将dis初始化为起点的出边
    38         }
    39         
    40         
    41         
    42         for(int i = 0; i < N - 1;i++){//除去起点, 还剩n-1个点不在生成树中
    43            double mind = inf;
    44            int j,sel;
    45            for(j = 0; j < N; j++){
    46                 if(!vis[j] && dis[j] < mind){
    47                     mind = dis[j];
    48                     sel = j;
    49                 }
    50            }
    51            vis[sel] = 1;
    52            ans += dis[sel];
    53            for(int k = 0; k < N; k++){
    54                 if(!vis[k] && dis[k] > G[sel][k]){
    55                     dis[k] = G[sel][k]; //注意这里 prim是更新dis到选中点出边距离, dij是更新dis[选中点] + 选中点出边距离
    56                 }
    57            }
    58         }
    59         printf("%.2f
    ", ans);
    60     }
    61 }

    方法二: kruskal 复杂度(MlogM)

     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 int N;
     4 const int maxn = 1e3 + 7;
     5 const int inf = 0x3f3f3f3f;
     6 
     7 struct edge{
     8     int u;
     9     int v;
    10     double d;
    11     friend bool operator< (edge n1,edge n2){
    12         return n1.d<n2.d;
    13     }
    14 }
    15 ;
    16 edge m[maxn*maxn];
    17 
    18 
    19 
    20 double dis[maxn];
    21 bool vis[maxn];
    22 int x[maxn], y[maxn], f[maxn];
    23 
    24 int getf(int v){
    25     if(f[v] == v)
    26         return v;
    27     else{
    28         f[v] = getf(f[v]);
    29         return f[v];
    30     }
    31 }
    32 int mer(int v, int u){
    33     int t1, t2;
    34     t1 = getf(v);
    35     t2 = getf(u);
    36     if(t1 != t2){
    37         f[t2] = t1;
    38         return 1;
    39     }
    40     return 0;
    41 }
    42 
    43 double p2pdis(int x1, int y1, int x2, int y2){
    44     double dis = sqrt((x1-x2) * (x1 - x2) + (y1-y2) * (y1-y2));
    45     return dis;
    46 }
    47 int main(){
    48 
    49     while(scanf("%d", &N) && N){
    50         memset(vis,0,sizeof(vis));
    51         for(int i = 0; i < N; i++){
    52             scanf("%d %d", &x[i], &y[i]);
    53         }
    54 
    55         int mcnt = 0;
    56         for(int i = 0; i < N; i++){
    57             for(int j = 0; j < N; j++){
    58                 if(j != i){
    59                     m[mcnt].u = i;
    60                     m[mcnt].v = j;
    61                     m[mcnt++].d = p2pdis(x[i],y[i],x[j],y[j]);
    62                 }
    63             }
    64         }
    65         sort(m,m+mcnt); //从小到大排序边
    66 
    67         for(int i = 0; i < N; i ++){//并查集初始化
    68             f[i] = i;
    69         }
    70         double ans = 0;
    71         int cnt = 0;
    72         for(int i = 0; i < mcnt; i++){//从小到大枚举
    73             if(mer(m[i].u, m[i].v)){
    74 //                printf("u: %d v: %d
    ", m[i].u, m[i]. v);
    75                 cnt ++;
    76                 ans += m[i].d;
    77             }
    78             if( cnt == N - 1)//用了n-1条边后退出
    79                 break;
    80         }
    81         printf("%.2f
    ", ans);
    82     }
    83         return 0;
    84 }
  • 相关阅读:
    约瑟夫环问题(Joseph)
    Java变量及运算符
    浅谈 Hooks
    如何使用DBUtils
    mac webstrom 安装less
    字符流-缓冲区-自定义myBufferedReader
    跨平台换行符
    329.-io流(字符-练习-复制文本文件二)
    328.io流(字符串-练习-复制文本文件一)
    LockDemo 锁对象
  • 原文地址:https://www.cnblogs.com/Jadon97/p/7250702.html
Copyright © 2011-2022 走看看