题解 一个人的公司
Posted mhhx
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了题解 一个人的公司相关的知识,希望对你有一定的参考价值。
这道题 %10 的数据是为暴搜准备的。
根据题目中的连接成功条件,可以看出这是一题最小生成树,以最小的代价用 n -1 条边连接 n 个点。最小生成树有两种算法, Prim 和 kruskal 。
- 关于 Prim
它死了。
PrimPrim 的时间复杂度为 O(n^2}) ,本题数据量过大,只能通过 %80 的数据。出题者的意图正是要卡掉 Prim 。而 Kruskal 的时间复杂度为 O(ElogE) ,可以通过本题。
本题重点在于服务器的品牌及判断是否连接成功。
定义数组 b 储存每个服务器的品牌,输入边时判断两端是否为同一品牌,如果成立则边权为零。由于连接线价格等于边权,所以总钱数直接加边权即可。
根据最小生成树定律,如果 n 个点连接成功,则一定用上了 n−1 条边。设置计数器 k 记录用上的边个数,如果 k=n−1 ,则连接成功。
本题 std :
#include <bits/stdc++.h> using namespace std; struct edge {int x, y, v;} a[10000005]; int n, e, b[10000005], f[10000005], ans, k, m; inline bool cmp(const edge &a, const edge &b) {return a.v < b.v;} inline int find(int x) {if (f[x] != x) f[x] = find(f[x]); return f[x];} int main() { scanf("%d%d", &n, &e); for (register int i = 1; i <= n; i++) scanf("%d", &b[i]); for (register int i = 1; i <= e; i++) { scanf("%d%d%d", &a[i].x, &a[i].y, &a[i].v); // 预处理边权 if (b[a[i].x] == b[a[i].y]) a[i].v = 0; } // kruskal sort(a + 1, a + 1 + n, cmp); for (register int i = 1; i <= n; i++) f[i] = i; for (register int i = 1; i <= e; i++) { if (find(a[i].x) != find(a[i].y)) { ans += a[i].v; f[a[i].x] = a[i].y; k++; } if (k == n - 1) break; } if (k < n - 1) printf("Failed.\n"); else printf("%d\n", ans); return 0; }
以上是关于题解 一个人的公司的主要内容,如果未能解决你的问题,请参考以下文章