POJ 1797 Heavy Transports(定點到定點的任意路徑的最小邊權(需要用到:最大生成樹(最小生成樹改)、並查集))

一、題目描述

在這裏插入圖片描述

二、算法分析說明與代碼編寫指導

建議先看此題:https://blog.csdn.net/COFACTOR/article/details/104693081
此題求解最小瓶頸路的最大邊權,只需要把求解最小生成樹改成求解最大生成樹,並將返回最大邊權改爲返回最小邊權就可以了。

三、AC 代碼

#include<cstdio>
#include<algorithm>
#include<vector>
#pragma warning(disable:4996)
using namespace std;
template<size_t n> class union_find {
private:
	unsigned root[n], rank[n];
public:
	union_find<n>() { init(); }
	void init() {
		fill(rank, rank + n, 0);
		for (unsigned i = 0; i < n; ++i)root[i] = i;
	}
	unsigned find_root(const unsigned& v) {
		unsigned r = v, t = v, u;
		if (t == root[v])return v;
		while (r != root[r]) { r = root[r]; }
		while (t != r) { u = root[t], root[t] = r, t = u; }
		return r;
	}
	void merge(const unsigned& u, const unsigned& v) {
		unsigned fu = find_root(u), fv = find_root(v);
		if (rank[fu] <= rank[fv]) { root[fu] = fv; if (rank[fu] == rank[fv])++rank[fv]; }
		else { root[fv] = fu; }
	}
};
struct edge { unsigned u, v, w; };
inline bool cmp(const edge& lhs, const edge& rhs) { return lhs.w > rhs.w; }
unsigned t, n, m; vector<edge> e; edge e0; union_find<1001> u;
inline unsigned kruskal() {
	sort(e.begin(), e.end(), cmp); vector<edge>::const_iterator i = e.begin();
	for (;;) {
		if (u.find_root(i->u) != u.find_root(i->v)) {
			u.merge(i->u, i->v);
			if (u.find_root(1) == u.find_root(n))return i->w;
		}
		++i;
	}
}
int main() {
	scanf("%u", &t);
	for (unsigned i = 1; i <= t; ++i) {
		scanf("%u%u", &n, &m); e.clear(); u.init();
		for (unsigned j = 1; j <= m; ++j) {
			scanf("%u%u%u", &e0.u, &e0.v, &e0.w);
			e.push_back(e0); swap(e0.u, e0.v); e.push_back(e0);
		}
		printf("Scenario #%u:\n%u\n\n", i, kruskal());
	}
	return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章