Charge-station HDU - 4435 (贪心)

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("");
    }
}

猜你喜欢

转载自www.cnblogs.com/ruthank/p/11365942.html