• 克鲁斯卡尔Kruskal


    Description

      在B 国里,有N 个城市,每个城市有一个发达程度a[i]。B 要修建一些道路,修建这条道路的花费为cost[i],把这些城市连起来,使得任意2 个城市之间,有且只有1 条路相联通。最后这些道路建成时,每个城市对B 国的经济会做出贡献,贡献度为a[i] *(i 这个城市它所直接相连的城市数)(但由于B 国的人民只热衷于翻墙,所以经济并不发达,这个贡献值会远远小于cost)。这样B 就得出了一个对这个方案的代价,为总cost-总贡献值,现在B 要求一种方案使得这个代价最小。

    Input

    第一行两个数n,m,表示城市数量,可以修建的道路条数m。
    接下来1 行n 个数,表示a[i]。
    接下来M 行,每行3 个数,x,y,z,表示一条从x 到y 的双向边,修这条路
    的代价为z。

    Output

    一个数表示最小代价。

    Sample Input

    3 3
    1 2 3
    1 2 21
    1 3 21
    2 3 22

    Sample Output

    34

    思路:把代价看作 每条边-这条边连接城市的价值,这样就可以跑最小生成树了~
     1 #include <cstdio>
     2 #include <cstring>
     3 #include <algorithm>
     4 #define maxx 100010
     5 #define ll long long
     6 using namespace std;
     7 struct Edge{
     8     int u,v,w;
     9 }e[maxx];
    10 int a[maxx];
    11 int father[maxx];
    12 int n,m,x,y,v,cnt,blockcnt;
    13 ll ans;
    14 bool cmp(Edge a,Edge b){
    15     return a.w<b.w;
    16 }
    17 int find(int x){//找x所对应的根结点标号
    18     int s;
    19     for(s=x;father[s]>=0;s=father[s]){//find father
    20         while(s!=x){//路径压缩
    21             int tmp=father[x];
    22             father[x]=s;
    23             x=tmp;
    24         }
    25     }
    26     return s;
    27 }
    28 void connect(int u,int v){
    29     int r1=find(u),r2=find(v);
    30     int tmp=father[r1]+father[r2];//集合元素个数
    31     if(father[r1]>father[r2]){//r2元素多,r1接到r2上(优化)
    32         father[r1]=r2;
    33         father[r2]=tmp;//更新集合个数
    34     }
    35     else{
    36         father[r2]=r1;
    37         father[r1]=tmp;
    38     }
    39     return ;
    40 }
    41 int main(){
    42     scanf("%d%d",&n,&m);
    43     blockcnt=n;
    44     for(int i=1;i<=n;i++){
    45         scanf("%d",&a[i]);
    46     }
    47     for(int i=1;i<=m;i++){
    48         scanf("%d%d%d",&x,&y,&v);
    49         e[i].u=x;
    50         e[i].v=y;
    51         e[i].w=v-a[x]-a[y];
    52     }
    53     sort(e+1,e+1+m,cmp);
    54     for(int i=1;i<=n;i++){
    55         father[i]=-1;
    56     }
    57     for(int i=1;i<=m;i++){
    58         if(blockcnt==1)
    59             break;
    60         if(find(e[i].u)!=find(e[i].v)){
    61             connect(e[i].u,e[i].v);
    62             blockcnt--;
    63             ans+=e[i].w;
    64         }
    65     }
    66     printf("%lld
    ",ans);
    67     return 0;
    68 }
  • 相关阅读:
    友盟统计,监听事件次数。
    webView 加载网页
    Springboot 启动时Bean初始化,启动异常-Assert.isTrue(condition,message) 报错
    Springboot使用@ConfigurationProperties注解 配置读不进去
    2018即将结束,给寒假李哥flag
    大精度求和,给任意两个数 m,n 甚至m,n->∞ 计算x+y
    第二章JavaScript 函数和对象
    第三章JavaScript 内置对象
    响应式网页设计
    新的页面布局方式
  • 原文地址:https://www.cnblogs.com/al76/p/8573848.html
Copyright © 2020-2023  润新知