首页 > 代码库 > POJ3723 Conscription
POJ3723 Conscription
PS: 分析这是一道不错的题目,要求去抽象。
直接说结论: 题目可能是许森林,每一个森林有一颗最小生成树并且选择第一个点花费为10000。
这道题目实现的时候我对0 ~ M进行了编码为 N 到 M+N-1。
#include <iostream> #include <cstdio> #include <cstring> #include <algorithm> #include <vector> using namespace std; const int MAXN = 20010; struct edge { int from, to, w; }; vector<edge> edges; int f[MAXN]; int N, M, R; bool cmp(edge x, edge y) { if(x.w != y.w) return x.w < y.w; else return false; } int getFather(int x) { if(f[x] == x) return x; else return f[x] = getFather(f[x]); } int work() { const int bound = N+M; for(int i = 0; i < bound; i++) f[i] = i; sort(edges.begin(), edges.end(), cmp); long long tot = 0; for(int i = 0; i < (int)edges.size(); i++) { edge &t = edges[i]; int f1 = getFather(t.from); int f2 = getFather(t.to); if(f1 != f2) { f[f1] = f2; tot += t.w; } } int cnt = 0; for(int i = 0; i < bound; i++) { if(f[i] == i) cnt++; } return 10000*cnt + tot; } int main() { int T; scanf("%d", &T); while(T--) { scanf("%d%d%d", &N, &M, &R); edges.clear(); int x, y, w; edge t; for(int i = 1; i <= R; i++) { scanf("%d%d%d", &x, &y, &w); w = 10000-w; y = y + N; // encoding. t.from = x; t.to = y; t.w = w; edges.push_back(t); } int res = work(); printf("%d\n", res); } return 0; }
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。