OR53. 寻宝
描述
亮亮解出了卷轴隐藏的秘密,来到了一片沼泽地。这里有很多空地,而面试直通卡可能埋在任意一块空地中,好在亮亮发现了一堆木材,他可以将木材铺在两个空地之间的沼泽地上。因为亮亮不知道面试直通卡具体在哪一块空地中,所以必须要保证任意一块空地对于亮亮来说是可以抵达的。 “怎么还有鳄鱼!没办法,看来有些空地不能直接到达了。” 亮亮虽然没有洁癖,但是沼泽地实在太臭了,所以亮亮不会循环利用木材。而且木材不能拼接在一起使用,所以亮亮必须要知道在耗费木材最少的情况下,最长的那根木材至少需要多长。输入描述
第一行包含两个整数N(1≤N≤10000),M(1≤M≤1000000)。N表示公有N块空地。 接下来M行,每行包含三个整数P(1≤P≤N),Q(1≤Q≤N),K代表P,Q两个间没有鳄鱼,需要耗费K的木材。输出描述
一个整数,即耗费木材最少的情况下,最长的那根木材长度。示例1
输入:
4 3 1 2 1 2 3 1 3 4 2
输出:
2
C++ 解法, 执行用时: 4ms, 内存消耗: 480KB, 提交时间: 2018-04-29
#include <stdio.h> #include <iostream> #include <vector> #include <algorithm> using namespace std; typedef struct Node { int p; int q; int k; }node; vector<int> pre; int unionsearch(int index) { while (pre[index] != index) { pre[index] = pre[pre[index]]; index = pre[index]; } return index; } void join(int x, int y) { if (pre[x] != pre[y]) { pre[x] = y; } } bool cmp(const node& vn1, const node & vn2) { return vn1.k < vn2.k; } int main(void) { int N, M; scanf("%d %d", &N, &M); vector<node> vn; for (int i = 0; i < M; i++) { node tmp; scanf("%d %d %d", &tmp.p, &tmp.q, &tmp.k); vn.push_back(tmp); } // initialize union set; for (int i = 0; i <= N; i++) { pre.push_back(i); } sort(vn.begin(), vn.end(), cmp); int res = 0; for (int i = 0; i < M; i++) { int rootA = unionsearch(vn[i].p); int rootB = unionsearch(vn[i].q); if (rootA != rootB) { if (res < vn[i].k) { res = vn[i].k; } join(rootA, rootB); } } cout << res << endl; return 0; }
C++ 解法, 执行用时: 5ms, 内存消耗: 384KB, 提交时间: 2020-12-23
#include <cstdio> #include <algorithm> using namespace std; static const int MAXN = 10003, MAXM = 1000003; struct Edge{ int a; int b; int w; bool operator< (const Edge& e) const { return w < e.w; } } edges[MAXM]; int parent[MAXN]; void add_edge(int a, int b, int w, int i) { edges[i].a = a; edges[i].b = b; edges[i].w = w; } int find_parent(int n) { if(parent[n] != n) parent[n] = find_parent(parent[n]); return parent[n]; } int main() { int n, m; while(scanf("%d %d", &n, &m) != EOF) { for(int i=0; i<m; ++i) { int a, b, w; scanf("%d %d %d", &a, &b, &w); add_edge(a, b, w, i); } sort(edges, edges+m); for(int i=1; i<=n; ++i) parent[i] = i; int ans = -1; for(int i=0; i<m; ++i) { int pa = find_parent(edges[i].a); int pb = find_parent(edges[i].b); if(pa != pb) { parent[pa] = pb; if(edges[i].w > ans) ans = edges[i].w; } } printf("%d\n", ans); } return 0; }