크루스 칼 해체 설정된 최소 스패닝 트리

제목 설명
이도 연결되어 있지 않은 경우 무향 그래프 주어진 바와 같이, 최소 스패닝 트리가 출력 orz 얻어진다

입력 출력 형식
입력 형식 :
첫 번째 라인은 두 정수 N은 M이 N은 전체 노드도를 나타내고, M은 방향성이 에지를 포함한다. (N은 <= 5000, M < = 200,000)
다음 M 라인이 세 사이의 정수, 이순신 닫아 포함 닫아 노드 아니오 사이 이순신 접속 에지의 길이를 표현

출력 형식 :
출력들을 포함, 즉 트리 각 변의 길이에 걸쳐 최소한의 상기 출력 접속 orz도없는 경우.

샘플 입력 출력
입력 샘플 # 1
. 4 5
1 2 2
1 3 2
1 4 3
2 4 3
3 4 3.
출력 샘플 # 1 :
7

이 코드는 실제로 약간의 실수 등장,하지만 난 정말 무슨 잘못을 모른다. . .
글쎄, 난 나중에 병합 코드를 수정하는에 기록

#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