1016. Uniqueness of MST (35)解题报告

来源:互联网 发布:刷vip永久软件 编辑:程序博客网 时间:2024/06/08 20:16

原题链接:

1016. Uniqueness of MST (35)

解题思路:

运用Kruskal最小生成树算法。

  1. 用Kruskal最小生成树算法对输入数据进行操作;
  2. 算法输出连通分量只有1个,则存在最小生成树,否则不存在。
  3. 枚举最小生成树的每一条边,将该边从图中删去,然后对该图进行步骤1。
  4. 如果得到的最小生成树的总重等于步骤2得到最小生成树的总重,则最小生成树数量加一。
通过画面:
代码:
#define _CRT_SECURE_NO_WARNINGS#include <cstdio>#include <cstdlib>#include <cassert>#include <vector>#include <queue>#include <algorithm>#include <set>using namespace std;struct edge {int start, dest, weight, index;edge(int start = 0, int dest = 0, int weight = 0) : start(start), dest(dest), weight(weight) {index = 0;}bool operator<(const edge& e2) const{if (weight > e2.weight) {return true;}else if (weight == e2.weight && index > e2.index) {return true;}else {return false;}}};int kruskal(const vector<vector<edge>>& adjList, bool& flag, int& sumWeight);bool kruskal(const vector<vector<edge>>& adjList, edge taboo, int min);int findRoot(vector<int>& setArray, int index);void unionSet(vector<int>& setArray, int root1, int root2);int main(){int n = 0, m = 0;assert(scanf("%d %d", &n, &m) == 2);vector<vector<edge>> adjList(n + 1);for (int i = 0; i < m; i++) {edge tmp;assert(3 == scanf("%d %d %d", &tmp.start, &tmp.dest, &tmp.weight));tmp.index = i;adjList[tmp.start].push_back(tmp);}bool flag = true;int sumWeight = 0;int component = kruskal(adjList, flag, sumWeight);if (component > 1) {printf("No MST\n%d\n", component);}else {printf("%d\n", sumWeight);if (flag) {puts("Yes");}else {puts("No");}}return 0;}int kruskal(const vector<vector<edge>>& adjList, bool& flag, int& sumWeight){vector<int> setArray(adjList.size(), -1);priority_queue<edge> edgeLeft;vector<edge> MST;for (int i = 0; i < (int)adjList.size(); i++) {for (int j = 0; j < (int)adjList[i].size(); j++) {edgeLeft.push(adjList[i][j]);}}int cnt = adjList.size() - 2;while (cnt && !edgeLeft.empty()) {edge tmp = edgeLeft.top();edgeLeft.pop();int root1 = findRoot(setArray, tmp.start);int root2 = findRoot(setArray, tmp.dest);if (root1 != root2) {cnt--;unionSet(setArray, root1, root2);sumWeight += tmp.weight;MST.push_back(tmp);}}for (int i = 0; i < (int)MST.size() && flag; i++) {flag = kruskal(adjList, MST[i], sumWeight);}return cnt + 1;}bool kruskal(const vector<vector<edge>>& adjList, edge taboo, int min){vector<int> setArray(adjList.size(), -1);priority_queue<edge> edgeLeft;for (int i = 0; i < (int)adjList.size(); i++) {for (int j = 0; j < (int)adjList[i].size(); j++) {if (taboo.index != adjList[i][j].index) {edgeLeft.push(adjList[i][j]);}}}int cnt = adjList.size() - 2;int totalWeight = 0;while (cnt && !edgeLeft.empty()) {edge tmp = edgeLeft.top();edgeLeft.pop();int root1 = findRoot(setArray, tmp.start);int root2 = findRoot(setArray, tmp.dest);if (root1 != root2) {cnt--;unionSet(setArray, root1, root2);totalWeight += tmp.weight;}}if (cnt > 0) {return true;}else if (min != totalWeight) {return true;}else {return false;}}int findRoot(vector<int>& setArray, int index){if (setArray[index] < 0) {return index;}else {return setArray[index] = findRoot(setArray, setArray[index]);}}void unionSet(vector<int>& setArray, int root1, int root2){if (setArray[root1] < setArray[root2]) {setArray[root1] += setArray[root2];setArray[root2] = root1;}else {setArray[root2] += setArray[root1];setArray[root1] = root2;}}

原创粉丝点击