算法设计第二次上机作业-The Unique MST

           # 算法设计第二次上机作业-The Unique MST
题目描述

判断一个图的MST树是否唯一

输入
第一行是输入的测试样例的个数
后面的每一个样例的第一行都给出两个数n和m,给出了总节点数和边数。
之后的m行给出每条边的两个节点和权重。

输出
如果MST唯一,则输出权重
若不唯一,则输出"Not Unique!"

思路:

查找MST树用Krustal算法,将所有的边进行排序,每次都选择权重最小的边,判断这条边和已经在mst_edges中的边是否连通,若不连通则加入到集合中。
判断连通则是用并查集,并查集可以看这篇博客并查集详解

AC的代码:
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <vector>
#include <cstring>
#define Max 10005
using namespace std;
struct edge {
    int to;
    int from;
    int weight;
};
int p[Max]; //记录每个节点的上级节点(不是祖先)
edge edges[Max];
vector<int> mst_edges;

int cmp(edge edge1, edge edge2) {
    return edge1.weight < edge2.weight;
}

int find_root(int x) {	//并查集找到每一个节点的祖先节点
    if(p[x]!=-1) {
        return find_root(p[x]);
    }
    else {
        return x;
    }
}

void Krustal(int n, int m) {
    int num = 0, weight = 0;
    memset(p, -1, sizeof(p));
    mst_edges.clear();
    for(int i=0; i<m; i++) {
        if(num == n-1) break;
        int px = find_root(edges[i].from);
        int py = find_root(edges[i].to);
        if(px != py) {	//这条边和其他的边不连通
            p[px] = py;
            num++;
            weight += edges[i].weight;
            mst_edges.push_back(i);
        }
    }
    bool flag = true;
    int size = mst_edges.size();
    for(int i=0; i<size; i++) {	//去掉mst_edges中的每一条边,看剩下的边能否构成一棵MST树
        int ans = 0;
        num = 0;
        memset(p, -1, sizeof(p));
        for(int j=0; j<m; j++) {
            if(mst_edges[i] == j) continue;
            int px = find_root(edges[j].from);
            int py = find_root(edges[j].to);
            if(px != py) {
                p[px] = py;
                ans += edges[j].weight;
                num++;
            }
        }
        if(num == n-1 && ans == weight) {	//如果剩下的边能够构成一棵树并且权重和之前的相同,说明不唯一
            flag = false;
            break;
        }
    }
    if(flag == true) cout<<weight<<endl;
    else cout<<"Not Unique!"<<endl;
}

int main(int argc, const char * argv[]) {
    // insert code here...
    int num, n, m;
    scanf("%d",&num);
    for(int i=0; i<num; i++) {
        scanf("%d%d", &n, &m);
        for(int j=0; j<m; j++) {
            scanf("%d%d%d", &edges[j].from, &edges[j].to, &edges[j].weight);
        }
        sort(edges, edges+m, cmp);
        Krustal(n, m);
    }
    return 0;
}
出现的bug有:
  1. 中间出现过TEL,因为Max值设小了,所以如果值设小了不一定会出现Time Error
  2. 判断是否是树的时候一开始写成了边数-1,应该是节点数-1
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值