您的位置:首页 > 其它

HOJ2064 - Journey to Tibet - 并查集+暴力

2017-08-13 11:34 375 查看

Journey to Tibet

题目链接

分类
dsu
brute force


1.题意概述

​ 给出你n(1≤n≤1000)个寺庙的坐标,相邻两个寺庙,你最多只能走30km现在问你总哪个起点出发,能够走尽可能多的寺庙,相同则输出输入编号的最小值。

2.解题思路

这题本质是求最大的连通块,连通问题,我们都可以考虑用并查集维护,父亲就是集合里面id最小的,因为n很小,我们O(n2)地暴力维护任意两个寺庙的最短路径,然后再扫一遍集合求出最大值即可。

3.AC代码

vector<int> g
;
struct node {
int x, y, c;
} p
;
int pa
;
void init() {
rep(i, 0, N) {
g[i].clear();
pa[i] = i;
}
}
int find(int x) {
if (x == pa[x]) return x;
return pa[x] = find(pa[x]);
}
void merge(int a, int b) {
int a1 = find(a);
int b1 = find(b);
if (a1 == b1) return;
if (a1 < b1) pa[b1] = a1;
else pa[a1] = b1;
}
int getdis(int a, int b) {
return (p[a].x - p[b].x) * (p[a].x - p[b].x) + (p[a].y - p[b].y) * (p[a].y - p[b].y);
}
inline void solve() {
int n;
while (~scanf("%d", &n) && n) {
init();
rep(i, 1, n + 1) scanf("%d%d%d", &p[i].x, &p[i].y, &p[i].c);
rep(i, 1, n) {
rep(j, i + 1, n + 1) {
int dis = getdis(i, j);
if (dis <= 900) merge(i, j);
}
}
rep(i, 1, n + 1)  {
int fa = find(i);
g[fa].pb(i);
}
int P = 1, ans = 0;
rep(i, 1, n + 1) {
int sum = 0;
int u = i;
rep(j, 0, SZ(g[i])) {
u = min(u, g[i][j]);
sum += p[g[i][j]].c;
}
if (sum > ans) {
ans = sum;
P = u;
} else if (ans == sum && u < P) P = u;
}
printf("%d %d\n", P, ans);
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  acm