• 最小生成树模板【kruskal & prim】


    CDOJ 1966 Kruskal 解法

    时间复杂度O(mlogm) m为边数,这里主要是边排序占时间,后面并查集还好

     1 #include <cstdio>
     2 #include <cstring>
     3 #include <iostream>
     4 #include <algorithm>
     5 using namespace std;
     6 typedef long long LL;
     7 
     8 const int N=2002;
     9 const int M=2e5+2;
    10 int n,m,tot=0,num=0;
    11 LL ans=0;
    12 int f[N];
    13 struct Node
    14 {
    15     int u,v;
    16     LL w;
    17     bool operator < (const Node & b)
    18     {
    19         return w < b.w;
    20     }
    21 
    22 }G[M];
    23 
    24 int find(int x)
    25 {
    26     return x==f[x]?x:f[x]=find(f[x]);
    27 }
    28 
    29 int unite(int x,int y)
    30 {
    31     x=find(x);
    32     y=find(y);
    33     if(x!=y)f[x]=y;
    34 }
    35 
    36 void kruskal()
    37 {
    38     for(int i=1;i<=n;i++)f[i]=i;
    39     sort(G,G+tot);
    40     for(int i=0;i<tot;i++)
    41     {
    42         int u=find(G[i].u);
    43         int v=find(G[i].v);
    44         if(u!=v)
    45         {
    46             unite(u,v);
    47             ans+=G[i].w;
    48             num++;
    49         }
    50     }
    51     if(num==n-1)
    52     {
    53         cout<<"yes"<<endl;
    54         cout<<ans<<endl;
    55     }
    56     else
    57         cout<<"no"<<endl;
    58 }
    59 
    60 int main()
    61 {
    62 
    63     cin>>n>>m;
    64 
    65     while(m--)
    66     {
    67         int a,b,v,p;
    68         cin>>a>>b>>v>>p;
    69         if(p==0)continue;
    70         G[tot].u=a;
    71         G[tot].v=b;
    72         G[tot].w=v;
    73         tot++;
    74     }
    75     kruskal();
    76     return 0;
    77 }

    prim模板:主要用于稠密图,尤其是完全图的最小生成树

    时间复杂度为O(n^2),如果用最小堆优化,为O(mlogn) [实际为O((m+n)logn),假设m边数>=n顶点数,从而简写]  算法分为两部分,一个找当前最小值,一个根据当前点的临边更新数组。logn获取最小值并从堆中删除,后用logn执行一条边的更新

     1 int cost[N][N]; // 表示e=(u,v)的权值,不存在情况为INF
     2 int mincost[N]; // 从集合x出发的边到每个顶点的最小权值
     3 bool vis[N];    // 集合x内的顶点
     4 int V;      // 顶点数
     5 
     6 int prim()
     7 {
     8     for(int i=0;i<V;i++)
     9     {
    10         mincost[i]=INF;
    11         vis[i]=0;
    12     }
    13     mincost[0]=0; // 默认选第一个顶点为起始点
    14     int res=0;
    15 
    16     while(true)
    17     {
    18         int v=-1;
    19         for(int u=0;u<V;u++)
    20             if(!vis[u]&&(v==-1||mincost[u]<mincost[v]))v=u;
    21 
    22         if(v==-1)break;
    23         vis[v]=1;
    24         res+=mincost[v];
    25         for(int u=0;u<V;u++)
    26         {
    27             if(mincost[u]>cost[v][u])
    28                 mincost[u]=cost[v][u];
    29         }
    30     }
    31     return res;
    32 }
  • 相关阅读:
    redis线程模型
    同步容器和并发容器
    200+面试题
    redis pipeline
    redis事务和脚本
    redis事务
    redis优缺点
    redis持久化策略
    Redis为什么要把所有数据放到内存中?
    redis的过期策略以及内存淘汰机制
  • 原文地址:https://www.cnblogs.com/demian/p/9193915.html
Copyright © 2020-2023  润新知