Explore Tibet
.
题意:给一个图带边长和点权,问从随意一点出发,走不超过30的边长的路径,最多可以收获多少(点权)
.
.
解法:直接可以一起的并查集就好了,注意这题读入用!EOF来结束,我们队一直被这个坑tle了很多发0.0
.
.
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
using namespace std;
const int maxn = 10100;
int f[maxn], n, sum[maxn], a[maxn][3];
int ra[maxn];
int get(int x) {
if (f[x] == x) return x;
f[x] = get(f[x]);
return f[x];
}
int main() {
while (scanf("%d", &n)!=EOF&&n) {
for (int i = 1; i <= n; i++) f[i] = i, ra[i]=1;
for (int i = 1; i <= n; i++) {
scanf("%d %d %d", &a[i][1], &a[i][2], &a[i][0]);
for (int j = 1; j < i; j++) {
if ((a[i][1]-a[j][1])*(a[i][1]-a[j][1])+(a[i][2]-a[j][2])*(a[i][2]-a[j][2]) <= 900) {
int fi = get(f[i]);
int fj = get(f[j]);
if (fi == fj) continue;
if(ra[fi]<ra[fj])
{
f[fi]=fj;
ra[fj]+=ra[fi];
}
else
{
f[fj]=fi;
ra[fi]+=ra[fj];
}
/* if (fi < fj) {
f[fj] = fi;
} else if (fi > fj) {
f[fi] = fj;
}*/
}
}
}
for (int i = 1; i <= n; i++) if (f[i] != i) {
int x = get(f[i]);
a[x][0] += a[i][0];
}
int maxx = 0, ans = 0;
for (int i = 1; i <= n; i++) if (a[get(i)][0] > maxx) {
maxx = a[get(i)][0];
ans = i;
}
printf("%d %d\n", ans, maxx);
}
}