#hdu 4435 charge-station#

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4435

利用二进制的特殊性,对于第i个城市cost为2i-1,也就是说即使0~i-1号城市都建立加油站,

花费也赶不上在i点建加油站,所以,思路:先每个城市建加油站,从高往低变了,能不建的就不建。

对于去掉后判断时候可行,不难,一遍dfs就行:

如果u点,v点都有加油站,dis( u, v ) <= d;

如果u点有加油站,v点无加油站,dis( u, v ) <= d/2;(保证可以回来)

不说了,简单题,代码:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<vector>
#include<cmath>

using namespace std;
const int maxn = 200;
int n;
double d;
struct Node{
    double x, y;
}node[maxn];

int vis[maxn], ans[maxn];

double dis( int i, int j ){
    double x1 = node[i].x, y1 = node[i].y;
    double x2 = node[j].x, y2 = node[j].y;

    return ceil(sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2)));
}

void dfs( int u ){
    for( int v = 1; v <= n; ++v ){
        if( v == u || vis[v] == 1 )
            continue;
        if( ans[v] == 1 && dis( u, v ) <= d ){  //v点存在加油站且可达
            vis[v] = 1;
            dfs(v);
        }else if( ans[v] == 0 && dis( u, v ) <= d/2 ){  //v点无加油站但可达
            vis[v] = 1;
        }
    }
}

bool judge( int u ){
    ans[u] = 0;
    memset( vis, 0, sizeof(vis) );

    vis[1] = 1;
    dfs(1);

    int flag = 1;
    for( int i = 1; i <= n; ++i ){
        if(vis[i] == 0){
            flag = 0;
            break;
        }
    }

    //回退
    ans[u] = 1;
    return flag;
}

void solve(){
    for( int i = n; i >= 2; --i ){
        if(judge(i))
            ans[i] = 0;
    }
}

void print(){
    int e = n;
    for( int i = n; i >= 1; --i ){
        if( ans[i] == 0 )
            e--;
        else
            break;
    }

    for( int i = e; i >= 1; --i ){
        printf("%d", ans[i]);
    }
    printf("\n");
}

int main(){
    //freopen("4438.in", "r", stdin);
    while(scanf("%d%lf", &n, &d) != EOF){
        memset( node, 0, sizeof(node) );
        for( int i = 1; i <= n; ++i ){
            scanf("%lf%lf", &node[i].x, &node[i].y);
        }

        bool flag = 1;
        for( int i = 1; i <= n; ++i ){
            ans[i] = 1;

            bool flag1 = 0;
            for( int j = 1; j <= n; ++j ){
                if( i == j )
                   continue;
                if( dis( i, j ) <= d )
                    flag1 = 1;
            }

            if( flag1 == 0 ){
                flag = 0;
                break;
            }
        }

        //存在某一节点不可达
        if(!flag){
            printf("-1\n");
            continue;
        }

        solve();
        print();
    }

    return 0;
}
View Code

相关文章:

  • 2022-01-05
  • 2022-12-23
  • 2021-06-02
  • 2021-10-14
  • 2021-07-28
  • 2022-12-23
  • 2021-08-30
  • 2022-01-02
猜你喜欢
  • 2021-08-11
  • 2022-12-23
  • 2021-09-23
  • 2022-12-23
  • 2022-12-23
  • 2021-07-31
  • 2021-06-05
相关资源
相似解决方案