怎么求一幅图像的最小生成树

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了怎么求一幅图像的最小生成树相关的知识,希望对你有一定的参考价值。

两种算法:

举例说明:给出下图计算其最小生成树。

算法一:

算法二:

参考技术A

有两个经典算法:

算法一:

    从所有备选的边集合中选择权值最小的加入已选集合;

    检查是否产生回路,如果产生回路则去掉刚加入的边;

    返回第一步,直到备选的边集变为空;

算法二:

     任选一个顶点作为起始点,加入已选顶点集合中;

    从所有与已选集合顶点相连的边中,选择权值最小的一条边,将其对应的顶点加入已选集合;

    重复第二步,直到所有顶点都被选入已选顶点集合;

最小生成树计数

最小生成树计数

rt.1<=n<=100; 1<=m<=1000

先求一遍最小生成树以后, 把我们考虑同一边权的所有边。

我们发现,所有最小生成树中,同一边权的那些边,其实连了固定的一堆点。这是一个最小生成树的性质。

因此,只需对于同一边权的边,统计连这些点有几种连法。用乘法原理乘所有边就得到了答案。

#include <map>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;

const int maxn=1e5+5, maxm=1e5+5, mod=1e9+7;
struct Edge{
    int x, y, v;
}e[maxm];
int cnte;
bool cmp(const Edge &a, const Edge &b){
    return a.v<b.v; }
    
int fa[maxn];
int find(int x){ return fa[x]==x?x:fa[x]=find(fa[x]); }
map<int, int> maap;
int n, m, ans=1;

int popcount(int x){ int re=0;
    while (x) re+=x&1, x>>=1; return re; }

int main(){
    scanf("%d%d", &n, &m); int x, y, v, t=0;
    for (int i=0; i<m; ++i){
        scanf("%d%d%d", &x, &y, &v);
        e[cnte++]=(Edge){x, y, v}; }
    sort(e, e+m, cmp);
    for (int i=0; i<m; ++i){
        if (find(e[i].x)!=find(e[i].y)){
            ++maap[e[i].v]; fa[find(e[i].x)]=find(e[i].y);
            if (++t==n-1) break;
        }
    }
    if (t<n-1){ puts("0"); return 0; }
    memset(fa, 0, sizeof(fa)); int j=0, flag, now;
    for (int i=1; i<=m; ){
        for (j=i; e[j].v==e[j+1].v; ++j);
        if (!maap[e[i].v]) continue;  //这个边权里必须有能选的点
        for (int S=0; S<(1<<j-i+1); ++S){
            if (popcount(S)!=maap[e[i].v]) continue;
            flag=1; now=0;
            for (int k=i; k<=j; ++k){
                if (S>>(k-i)&1){
                    if (find(e[i].x)==find(e[i].y)){
                        flag=0; break; }
                }
            }
            if (flag) ++now;
        }
        (ans*=now)%=mod;
        i=j+1;
    }
    printf("%d
", ans);
    return 0;
}

注:代码勿看(qwq)

以上是关于怎么求一幅图像的最小生成树的主要内容,如果未能解决你的问题,请参考以下文章

最小生成树

图解:如何实现最小生成树(Prim算法与Kruskal算法)

为啥破圈法和避圈法为啥不能求一点至另一点的最短距离

最小生成树计数

最小k度限制生成树

lightoj 1029 最小生成树 + 最大生成树