charge-station HDU - 4435
题意:平面内有\(n\)个点,编号为\(1-n\)。第\(i\)个点建加油站的花费为\(2^{i-1}\)。车加满油后可以走的路程为\(d\)。现在要从\(1\)点开始可重复的走过所有点,问建造加油站的最小花费。
题解:因为第\(n\)个点建加油站的花费大于前面所有点花费的总和。可以假设初始都建加油站,贪心地从第\(n\)个点到第\(1\)个点,考虑去掉该点的加油站,判图是否联通。如果不联通则保留该点加油站。
代码:
#include <bits/stdc++.h>
#define fopi freopen("in.txt", "r", stdin)
#define fopo freopen("out.txt", "w", stdout)
using namespace std;
typedef long long LL;
const int maxn = 130 + 100;
const int inf = 0x3f3f3f3f;
const double eps = 1e-6;
int n, d, vis[maxn], ans[maxn], flag[maxn];
int x[maxn], y[maxn];
int dist(int a, int b) {
return (int)ceil(hypot(x[b]-x[a], y[b]-y[a]) - eps);
}
void dfs(int x) {
vis[x] = 1;
for (int i = 1; i <= n; i++) if (!vis[i]){
int l = dist(x, i);
if (ans[x] && ans[i] && l <= d) dfs(i);
else if ((ans[x] || ans[i]) && l*2 <= d) dfs(i);
}
}
bool check() {
memset(vis, 0, sizeof(vis));
dfs(1);
for (int i = 1; i <= n; i++)
if (!vis[i]) return false;
return true;
}
int main() {
//fopi;
while(~scanf("%d%d", &n, &d)) {
for (int i = 1; i <= n; i++)
scanf("%d%d", &x[i], &y[i]), ans[i] = 1;
if (!check()) {
printf("-1\n");
continue;
}
for (int i = n; i >= 2; i--) {
ans[i] = 0;
if (!check()) ans[i] = 1;
}
for (int i = n, cnt = 0; i >= 1; i--)
if (cnt = (ans[i] ? cnt+1:cnt)) printf("%d", ans[i]);
puts("");
}
}