📜  查找图是否为最小生成树 - C++ (1)

📅  最后修改于: 2023-12-03 15:10:44.072000             🧑  作者: Mango

查找图是否为最小生成树 - C++

最小生成树是一个连通无向图的生成树中边的权值和最小的生成树。

判断一个给定的图是否为最小生成树可以通过以下步骤完成:

  1. 首先将图按边权从小到大排序
  2. 从小到大遍历每一条边,并将其加入生成树(注意不能出现环)
  3. 如果生成树中有 $n - 1$ 条边($n$ 为图的节点数),则该生成树为最小生成树

以下是一个简单的C++程序,用于判断给定的图是否为最小生成树:

#include<bits/stdc++.h>
using namespace std;
const int MAXN=1e3+5,MAXM=1e6+5;
int head[MAXN],cnt=0,n,m,ans;
struct Edge{
    int u,v,w;
    bool operator<(const Edge &rhs)const{
        return w<rhs.w;
    }
}e[MAXM];
int find(int x){
    return head[x]==x?x:head[x]=find(head[x]);
}
void merge(int x,int y){
    head[find(x)]=find(y);
}
void kruskal(){
    sort(e+1,e+m+1);
    for(int i=1;i<=n;i++) head[i]=i;
    for(int i=1;i<=m;i++){
        int u=e[i].u,v=e[i].v,w=e[i].w;
        if(find(u)!=find(v)){
            merge(u,v);
            ans+=w;
        }
    }
}
int main(){
    scanf("%d%d",&n,&m);
    for(int i=1;i<=m;i++) scanf("%d%d%d",&e[i].u,&e[i].v,&e[i].w);
    kruskal();
    printf("%d\n",ans);
    return 0;
}

该程序使用了Kruskal算法来求解最小生成树,并在主函数中输出最小生成树的边权和。若输入的图是最小生成树,则程序输出的结果即为最小生成树的边权和。

以上程序中,变量n表示图的节点数,变量m表示图的边数。结构体Edge中的属性u、v、w分别表示一条边的起点、终点和权值。

在kruskal函数中,程序首先通过sort函数将图的边按边权排序,然后使用并查集来判断当前考虑的边是否可以加入生成树中(若两条边的起点和终点已经连通,则加入该边会构成环,故不能被加入)。

最后,程序输出了最小生成树的边权和。

代码片段

以下是程序的代码片段:

void kruskal(){
    sort(e+1,e+m+1);
    for(int i=1;i<=n;i++) head[i]=i;
    for(int i=1;i<=m;i++){
        int u=e[i].u,v=e[i].v,w=e[i].w;
        if(find(u)!=find(v)){
            merge(u,v);
            ans+=w;
        }
    }
}

int main(){
    scanf("%d%d",&n,&m);
    for(int i=1;i<=m;i++) scanf("%d%d%d",&e[i].u,&e[i].v,&e[i].w);
    kruskal();
    printf("%d\n",ans);
    return 0;
}

以上程序可以直接运行,用于判断一个给定的图是否为最小生成树。