POJ 3723 解题报告
2016-08-10 00:52
435 查看
这道题是最小生成树问题。由于“收集”每个人只能用一次“关系”,所以利用的关系不能形成环。贪心从最小的关系开始,只要不能形成环就收集。这就是kruskal用并查集的算法。最后没收集的人每人按最大代价加入总代价就可以了。
thestoryofsnow | 3723 | Accepted | 908K | 344MS | C++ | 2132B |
/* ID: thestor1 LANG: C++ TASK: poj3723 */ #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; const int MAXR = 50000; const int MAXN = 10000; const int MAXM = 10000; void makeset(const int N, int parent[], int rank[]) { for (int u = 0; u < N; ++u) { parent[u] = u; rank[u] = 0; } } int find(int u, int parent[]) { if (parent[u] != u) { parent[u] = find(parent[u], parent); } return parent[u]; } void union_set(int u, int v, int parent[], 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(int parent[], int rank[], const int N, Edge edges[], const int M, int &collected) { makeset(N, parent, rank); sort(edges, edges + M); int mst = 0; for (int i = 0; i < M; ++i) { Edge edge = edges[i]; if (find(edge.u, parent) != find(edge.v, parent)) { collected++; mst += edge.w; union_set(edge.u, edge.v, parent, rank); } } return mst; } int main() { int parent[MAXN + MAXM]; int rank[MAXN + MAXM]; Edge edges[MAXR]; int T; scanf("%d", &T); int N, M, R; int xi, yi, di; for (int t = 0; t < T; ++t) { scanf("%d%d%d", &N, &M, &R); for (int r = 0; r < R; ++r) { scanf("%d%d%d", &xi, &yi, &di); edges[r].u = xi; edges[r].v = N + yi; edges[r].w = 10000 - di; } int collected = 0; int mst = kruskal(parent, rank, N + M, edges, R, collected); int minimumPay = mst + (N + M - collected) * 10000; printf("%d\n", minimumPay); } return 0; }
相关文章推荐
- poj 3723 Conscription 最大生成树 解题报告
- POJ-1129 Channel Allocation 解题报告
- poj解题报告——2388
- poj 2152解题报告
- POJ 2362 POJ1011解题报告
- POj 1105解题报告
- POJ - 1837 Balance解题报告
- poj2159解题报告
- POJ 3692 二分图最大点独立集 解题报告
- poj 2312解题报告
- POJ_3278 Catch That Cow 解题报告
- POJ-1905 Expanding Rods 解题报告
- POJ 1637 网络流判混合欧拉回路 解题报告
- POJ-1861-Network 解题报告
- 解题报告 poj 3207
- POJ 2455 解题报告
- poj 1192-最优连通子集解题报告
- POJ1250解题报告补
- POJ 2593 Max Sequence 解题报告
- poj2051解题报告(优先队列)