• 最小生成树和最小树形图


    最小生成树 是在无向图中 是把所有点连接的最小边值;

    pri 算法:

    贪心的思想,每次选择那个入边最短的边。去更新

    在更新那个点的时候,记录一下那个最小的边

    s算法

    #include <bits/stdc++.h>
    using namespace std;
    #define ri register int 
    #define M 200005 
    #define N 5005 
    
    int fa[N];
    struct edge{
        int a,b;
        int val;
        bool operator <(const edge &t)const 
        {
            return val<t.val;
        }
    }p[M];
    
    int findd(int a)
    {
        
        if(fa[a]==a) return a;
        fa[a]=findd(fa[a]); //检查的时候每一步都要好好看,看函数进去的值是什么 是上层的父亲 
        return fa[a];
    }
    
    int n,m;
    long long ans;
    int main(){
        
        scanf("%d%d",&n,&m);
        for(ri i=1;i<=m;i++)
        {
            int a,b,c;
            
            scanf("%d%d%d",&a,&b,&c);
            p[i].val=c;
            p[i].a=a,p[i].b=b;
            
        }
        
        sort(p+1,p+1+m);
        for(ri i=1;i<=n;i++)
        fa[i]=i;
        int trmp=0;
        for(ri i=1;i<=m;i++)
        {
           int l=findd(p[i].a);
           int r=findd(p[i].b);
           if(l==r) continue ;
           
           if(l!=r)
           {
             fa[l]=r;
             ans+=p[i].val;
             trmp++;
           }
        }
        if(trmp==n-1)
        printf("%lld",ans);
        else
        printf("orz");
        return 0;
        
    }
    View Code

    不能用prm 算法解决 最小树形图

    最小树形图 是有向图的最小生成树

    算法 zhuliu

    思想: 从入度入手+缩点的思想;

    void zl()
    {
        while(1){
        
        for(ri i=1;i<=n;i++) dis[i]=inf;
        
        for(ri i=1;i<=m;i++)
        {
            int u,v;
            u=p[i].u,v=p[i].v;
            if(v!=u&&dis[v]>p[i].val){
            pre[v]=u;
            dis[v]=p[i].val;
            }
        }
        for(ri i=1;i<=n;i++)
        {
            if(dis[i]==inf&&i!=root) /// 
            {
                printf("-1");
                exit(0);    
            }
        }
        int cnt=0;
        for(ri i=1;i<=n;i++) vis[i]=0,id[i]=0;
        
        for(ri i=1;i<=n;i++)
        {
            if(i==root) continue;
            ans+=dis[i];
            
            int v=i;
            while(vis[v]!=i&&!id[v]&&v!=root) /// 找循环 
            {
                vis[v]=i;
                v=pre[v];
            }
            if(!id[v]&&v!=root) /// 很 妙 妙 妙 
            {
                id[v]=++cnt;
                for(int u=pre[v];u!=v;u=pre[u])
                {
                    id[u]=cnt;
                }
            }
        }
        if(!cnt) 
        {
            printf("%d",ans);
            exit(0);
        }
        for(ri i=1;i<=n;i++)
        {
            if(!id[i]) id[i]=++cnt;
        }
        for(ri i=1;i<=m;i++)
        {
            int v=p[i].v, u=p[i].u;  //////// 新编号 
            p[i].v=id[v];
            p[i].u=id[u];
            if(id[u]!=id[v])
            {
                p[i].val-=dis[v];
            }
        }
        n=cnt;
        root = id[root];
    
    }
        
    }
    View Code
  • 相关阅读:
    git 根据tag创建分支
    前端自适应背景框
    ps快速切图与切片模板复用
    【动植物研究动态】20220626文献解读
    Easy Sum
    斯特林数笔记
    Educational Codeforces Round 128 (Rated for Div. 2)
    Unity 在Preferences或Project Setting窗口创建自定义配置
    诡异js面试题&知识点
    phpstorm修改快捷方式
  • 原文地址:https://www.cnblogs.com/Lamboofhome/p/15530542.html
Copyright © 2020-2023  润新知