POJ 2458 解题报告

来源:互联网 发布:梦幻西游定心术算法 编辑:程序博客网 时间:2024/06/08 00:26

刚开始用的是quick-select选取第N - 1小的边,感觉挺有道理的,没有意识到前N-1小的边可能会构成环。所以这道题还是要求最小生成树,然后里面的边就保证能够将所有的点都连接起来。最小生成树里面最大的那条边即为所求。

2485Accepted788K235MSC++2953B

/* ID: thestor1 LANG: C++ TASK: poj2485 */#include <iostream>#include <fstream>#include <cmath>#include <cstdio>#include <cstring>#include <limits>#include <string>#include <vector>#include <list>#include <set>#include <map>#include <queue>#include <stack>#include <algorithm>#include <cassert>using namespace std;int quickselect(vector<int> &dis, int k){int left = 0, right = dis.size() - 1;int pivot;while (left <= right){pivot = dis[left];int i = left + 1, j = right;while (true){while (i <= right && dis[i] <= pivot){i++;}while (dis[j] > pivot){j--;}if (i < j){int tmp = dis[i];dis[i] = dis[j];dis[j] = tmp;i++;j--;}else{break;}}int tmp = dis[left];dis[left] = dis[j];dis[j] = tmp;if (j - left + 1 == k){return pivot;}else if (j - left + 1 < k){k -= j - left + 1;left = j + 1;}else{right = j - 1;}}assert (false);return -1;}void makeset(const int N, std::vector<int> &parent, std::vector<int> &rank){for (int u = 0; u < N; ++u){parent[u] = u;rank[u] = 0;}}int find(int u, std::vector<int> &parent){if (parent[u] != u){parent[u] = find(parent[u], parent);}return parent[u];}void union_set(int u, int v, std::vector<int> &parent, std::vector<int> &rank){int ru = find(u, parent);int rv = find(v, parent);if (ru == rv){return;}if (rank[ru] < rank[rv]){parent[ru] = rv;}else if (rank[rv] < rank[ru]){parent[rv] = ru;}else{parent[ru] = rv;rank[rv]++;}}class Edge{public:int u, v, w;Edge() {}Edge(int u, int v, int w) : u(u), v(v), w(w) {}bool operator< (const Edge &rhs) const{if (this->w != rhs.w){return this->w < rhs.w;}return this->u < rhs.u || (this->u == rhs.u && this->v < rhs.v);}};int kruskal(const int N, std::vector<Edge> &edges){std::vector<int> parent(N);std::vector<int> rank(N);makeset(N, parent, rank);sort(edges.begin(), edges.end());// int mst = 0;int n = 0;for (int i = 0; i < edges.size(); ++i){Edge edge = edges[i];if (find(edge.u, parent) != find(edge.v, parent)){// mst += edge.w;n++;union_set(edge.u, edge.v, parent, rank);if (n == N - 1){return edge.w;}}}assert (false);return -1;}int main(){int T;scanf("%d", &T);for (int t = 0; t < T; ++t){int N;scanf("%d", &N);std::vector<Edge> edges;for (int i = 0; i < N; ++i){for (int j = 0; j < N; ++j){int d;scanf("%d", &d);if (i < j){edges.push_back(Edge(i, j, d));}}}int mst = kruskal(N, edges);cout << mst << endl;}return 0;  }


0 0
原创粉丝点击