クラスカル互いに素セットの最小スパニングツリー

タイトル説明
したように、この図は、出力に接続されていない場合、無向グラフが与えられると、最小全域木が得られ、ORZ

入力出力形式
入力形式:
最初の行は、2つの整数N、Mを含み、Nは総図ノードを表し、Mは、エッジを無向。(N <= 5000、M < = 200000)は
次にM線は三つの整数Xiの、李、紫が含まれ、紫は李、ノードなしXiに接続されたエッジの長さを表現しました

出力形式:
出力は、スパニングツリーの数、すなわち、最小の各辺の長さが含まれ、出力は図ORZ接続されていない場合。

サンプル入力出力
入力サンプル#1:
4 5
1 2 2
1 3 2
1 4 3
2 3 4
。3. 4. 3
出力サンプル#1:
7

このコードは、実際には小さなミスを見えたが、私は本当に何を間違ったのか分かりません。
まあ、私は後でマージコードを変更し、Aに書き込むこと

#include<iostream>
#include<stdio.h>
#include<algorithm>
using namespace std;
//最小生成树之kruskal 也就是使用并查集
//第一个是判断 边是否在同一个子集之中 第二个就是判断 边之间的合并
int a[100]={0};//
//再创建一个结构体数组来存储 起点,终点 和边的长度
struct jj{
    int x,y,z;
}J[100];
//写一个判断祖宗的方法
int zuzong(int x){
    if(a[x]==x)
        return x;
    else
        return zuzong(a[x]);
}
//写一个判断的方法
bool check(int x,int y){
   return zuzong(x)==zuzong(y);
}

//再写一个合并的方法
void merge_1(int x,int y){
    if(!check(x,y))
    a[zuzong(x)]=zuzong(y);

}
//再写一个比较的方法,用边的长度作为比较对象
bool cmp(jj x,jj y){//名字要取好
    return x.z<y.z;
}
int main()
{
    int N,M;//有n个结点,M条边
    int sum=0;
    int co=0;//这个是记录边数目,也就是能不能生成最小生成树
    int i;
    //先对结点和边进行输入
    scanf("%d%d",&N,&M);
    for(i=0;i<M;i++){
        scanf("%d%d%d",&J[i].x,&J[i].y,&J[i].z);
    }
    //然后按照思想,先对边进行从小到大排序,然后使用并查集对边的顶点进行判断是否在同一个集合中
    sort(J,J+M,cmp);
    //对几个结点的祖宗赋初值,都是等于自己
    for(i=1;i<=N;i++)
        a[i]=i;

    //然后开始判断
    for(i=0;i<M;i++){//从第一条边到最后一条边
        if(!check(J[i].x,J[i].y)){//如果这条边的两个点不在同一个集合,那就合并,并且记录长度
            merge_1(J[i].x,J[i].y);
            sum+=J[i].z;
            co++;
        }
    }

    //最后输出
    if(co==N-1)
        printf("%d",sum);
    else
        printf("orz");

}











公開された72元の記事 ウォンの賞賛5 ビュー2809

おすすめ

転載: blog.csdn.net/qq_41115379/article/details/104928766