列表

详情


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;
}

上一题