zoukankan      html  css  js  c++  java
  • 3366 【模板】最小生成树(Prim)

    题目描述

    如题,给出一个无向图,求出最小生成树,如果该图不连通,则输出orz

    输入输出格式

    输入格式:

    第一行包含两个整数N、M,表示该图共有N个结点和M条无向边。(N<=5000,M<=200000)

    接下来M行每行包含三个整数Xi、Yi、Zi,表示有一条长度为Zi的无向边连接结点Xi、Yi

    输出格式:

    输出包含一个数,即最小生成树的各边的长度之和;如果该图不连通则输出orz

    代码:

     1 #include<iostream>
     2 #include<vector>
     3 #include<queue>
     4 #include<algorithm>
     5 using namespace std;
     6 const int inf = 1<<30;
     7 int n, m;
     8 struct edge{
     9     int k, w;
    10 };
    11 bool operator<(const edge&e1, const edge&e2){
    12     return e1.w > e2.w;
    13 }
    14 priority_queue<edge>pq;
    15 vector<vector<edge> >v;
    16 int d[5010];
    17 bool used[5010];
    18 
    19 int main(){
    20     cin>>n>>m;
    21     int i;
    22     int donenum = 0;
    23     v.clear();
    24     v.resize(n+1);
    25     edge p, p2;
    26     for(i = 1; i <= m; i++){
    27         int a, b, c;
    28         cin>>a>>b>>c;
    29         p.k = b;
    30         p.w = c;
    31         v[a].push_back(p);
    32         p2.k = a;
    33         p2.w = c;
    34         v[b].push_back(p2);
    35     }
    36     for(i = 1; i <= n; i++) d[i] = inf;
    37     p.k = 1;
    38     p.w = 0;    
    39     int way = 0; 
    40     pq.push(p);
    41     while(!pq.empty()&&donenum<n){
    42         p = pq.top();
    43         pq.pop();
    44         if(used[p.k]) continue;
    45         way += p.w; donenum++;
    46         used[p.k] = true;
    47         for(i = 0; i < v[p.k].size(); i++){
    48             edge q;
    49             q.k = v[p.k][i].k;
    50             if(used[q.k]) continue;
    51             q.w = v[p.k][i].w;
    52             pq.push(q);
    53         }
    54     }
    55     if(donenum<n) cout<<"orz";
    56     else cout<<way;
    57     return 0;
    58 }

    备注:

    借着刚默写完一遍dijkstra的劲头,把Prim过了一遍。Prim跟dijkstra神似嘛,所以就想怎么把dijkstra改成Prim。因为gw的ppt上Prim的写法和dijkstra还是有些区别的。。

    两个算法很小的区别已在代码中标出。最开始我特别nc,以为在pop后把p.w的值加起来就行了,实际上,p.w是每个点到源点的距离,而不是到最小生成树的距离,所以当然不能这么加。

    要改的关键就是要记录下来每个点到最小生成树的距离,而不是到源点的距离。所以实际上只要改标黄那三行就可以了!ps:我是写着写着才突然发现实际上就是把dijkstra的q.w = p.w + v[p.k][i].w改成q.w = v[p.k][i].w就行了。

    看来对dijkstra的深刻理解还是很有价值的。hhh

  • 相关阅读:
    swift
    swift
    swift
    swift
    swift
    swift
    swift
    选择排序
    组合 和 继承
    Android中使用LitePal操控SQLite数据库
  • 原文地址:https://www.cnblogs.com/fangziyuan/p/6024008.html
Copyright © 2011-2022 走看看