zoukankan      html  css  js  c++  java
  • Codeforces Round #529 (Div. 3) F.Make It Connected

    传送门

    题意:

      有 n 个顶点,每个顶点有个花费 a[ i ],连接顶点 u,v 需要花费 a[v]+a[u]的代价。

      有 m 个特殊边,每条边有三个参数 u,v,w 代表的意思是连接 u,v 的花费可以不是 a[v]+a[u] 而是 w(当然选择小的那个啦)。

      求联通所有的顶点需要的最少花费?

    题解:

      首先,需要建图,改如何建呢?

      考虑到贪心的思路,首先不考虑 m 个特殊边,如何用最少的花费联通所有顶点呢?

      答案是找到 a[ i ] 最少的顶点 i,其他 n-1 个顶点全部连向 i 。

      将这 n-1 条边记录下来,在加上 m 条特殊边,然后,就是求最小生成树的模板题了,emmmmmm

    AC代码:

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<algorithm>
     4 #include<vector>
     5 using namespace std;
     6 #define ll __int64
     7 #define pb(x) push_back(x)
     8 const int maxn=2e5+10;
     9 
    10 int n,m;
    11 ll a[maxn];
    12 struct Node
    13 {
    14     int u,v;
    15     ll w;
    16     Node(int a,int b,ll c):u(a),v(b),w(c){}
    17 };
    18 vector<Node >G;
    19 void addEdge(int u,int v,ll w)
    20 {
    21     G.pb(Node(u,v,w));
    22 }
    23 
    24 int fa[2*maxn];
    25 int Find(int x)
    26 {
    27     int r=x;
    28     while(r != fa[r])
    29         r=fa[r];
    30     while(fa[x] != r)
    31     {
    32         int temp=fa[x];
    33         fa[x]=r;
    34         x=temp;
    35     }
    36     return r;
    37 }
    38 bool Union(int x,int y)
    39 {
    40     x=Find(x),y=Find(y);
    41     if(x != y)
    42     {
    43         fa[x]=y;
    44         return true;
    45     }
    46     return false;
    47 }
    48 bool cmp(Node _a,Node _b)
    49 {
    50     return _a.w < _b.w;
    51 }
    52 ll Solve()
    53 {
    54     sort(G.begin(),G.end(),cmp);
    55     ll res=0;
    56     for(int i=0;i < G.size();++i)
    57     {
    58         Node e=G[i];
    59         if(Union(e.u,e.v))
    60             res += e.w;
    61     }
    62     return res;
    63 }
    64 int main()
    65 {
    66     scanf("%d%d",&n,&m);
    67     int minP=0;
    68     for(int i=1;i <= n;++i)
    69     {
    70         fa[i]=i;
    71         scanf("%I64d",a+i);
    72         minP=(minP == 0 || a[minP] > a[i] ? i:minP);
    73     }
    74     for(int i=1;i <= n;++i)
    75         addEdge(i,minP,a[i]+a[minP]);
    76     for(int i=1;i <= m;++i)
    77     {
    78         int u,v;
    79         ll w;
    80         scanf("%d%d%I64d",&u,&v,&w);
    81         addEdge(u,v,w);
    82     }
    83     printf("%I64d",Solve());
    84     return 0;
    85 }
    Kruskal

     

      

  • 相关阅读:
    Webform服务器控件调用JS
    Webfrom基础知识
    Webform用户控件
    数组练习
    整理
    SVN分支与合并
    根据经纬度,获取两点间的距离
    简单Bat文件编写
    Maven Android使用一
    Maven环境配置
  • 原文地址:https://www.cnblogs.com/violet-acmer/p/10200867.html
Copyright © 2011-2022 走看看