Journey to Tibet
分類:
dsu
brute force
1.題意概述
- 給出你
n(1≤n≤1000) 個寺廟的座標,相鄰兩個寺廟,你最多隻能走30km 現在問你總哪個起點出發,能夠走儘可能多的寺廟,相同則輸出輸入編號的最小值。
2.解題思路
- 這題本質是求最大的連通塊,連通問題,我們都可以考慮用並查集維護,父親就是集合裏面id最小的,因爲n很小,我們
O(n2) 地暴力維護任意兩個寺廟的最短路徑,然後再掃一遍集合求出最大值即可。
3.AC代碼
vector<int> g[N];
struct node {
int x, y, c;
} p[N];
int pa[N];
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);
}
}