HDU 4435

题意:给出N个城市,从1开始需要遍历所有点,选择一些点建立加油站,使得花费最少 第i个城市要花费 2^(i-1)

思路: 因为建造最后一个加油站的花费是前面全部建造加油站的总和   所以从n开始遍历 看哪个可以不建造加油站(代码中的check) 用bfs检查 从加油站出发遍历到各个可以到达的点    并遍历出距离每个点的最近的加油站的距离dist[i]是多少  最后检查是否都能走到 可以返回true  不然返回false

代码:

#include<cstdio>
#include<cstring>
#include<cmath>
#include<queue>
#include<algorithm>
using namespace std;
const int INF = 10000000000;
int n, d, g[105][105], dist[105], res[105];
bool check()
{
    bool vis[105];
    memset(vis, false, sizeof(vis));
    queue<int >Q;
    for(int i=0;i<n;i++)
    {
        if(res[i]) dist[i]=0;
        else dist[i]=INF;
    }
    Q.push(0);
    vis[0]=true;
    while(!Q.empty())
    {
        int u=Q.front();
        Q.pop();
        for(int i=0;i<n;i++)
        {
            if(vis[i]==false&&g[u][i]<=d)
            {
                dist[i]=min(dist[i], dist[u]+g[u][i]);
                if(res[i])
                {
                    Q.push(i);
                    vis[i]=true;
                }
            }
        }
    }
    for(int i=0;i<n;i++)
    {
        if(res[i]==1&&!vis[i])
            return false;
        else if(res[i]==0&&dist[i]*2>d)
            return false;
    }
    return true;
}
int main()
{
    while(~scanf("%d%d", &n, &d))
    {
        double a[105], b[105];
        for(int i=0;i<n;i++)
        {
            scanf("%lf%lf", &a[i], &b[i]);
        }
        memset(g, 0, sizeof(g));
        for(int i=0;i<n;i++)
        {
            for(int j=0;j<n;j++)
            {
                if(i==j)
                    continue;
                g[i][j]=g[j][i]=ceil(sqrt((a[i]-a[j])*(a[i]-a[j])+(b[i]-b[j])*(b[i]-b[j])));
            }
        }
        for(int i=0;i<=n;i++)
            res[i]=1;
        if(!check())
        {
            printf("-1\n");
            continue;
        }
        for(int i=n-1;i>0;i--)
        {
            res[i]=0;
            if(!check())
                res[i]=1;
        }
        int flag=0;
        for(int i=n-1;i>=0;i--)
        {
            if(res[i]==1)
                flag=1;
            if(flag==1)
                printf("%d", res[i]);
        }
        printf("\n");
    }
}

时间: 2024-10-06 10:02:28

HDU 4435的相关文章

HDU 4435 charge-station () bfs图论问题

E - charge-station Time Limit:1000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u Submit Status Practice HDU 4435 Appoint description: Description There are n cities in M^3's empire. M^3 owns a palace and a car and the palace resides in

Hdu 4435 charge-station(BFS+贪心)

题目地址:http://acm.split.hdu.edu.cn/showproblem.php?pid=4435 思路:编号大的点应尽量避免建立加油站(2^0+2^1+2^2+......+2^i<2^(i+1)),所以先假设全部建站,若此时仍不能满足题意,则无解.否则,从n开始枚举点,尝试该点不建立加油站是否能满足题意(dist[i]表示节点i到最近加油站的距离,若i不为加油站则若dist[i]*2>d则不符合题意(从某加油站出发到i,从i并不能返回加油).若i为加油站,则若从加油站1不能

HDU 4435 charge-station (2012年天津赛区现场赛E题)

1.题目描述:点击打开链接 2.解题思路:本题利用DFS解决.不过本题的解法颇为巧妙,注意到2^0+2^1+...+2^(i-1)<2^i,这就意味着即使在0~i-1都建立加油站,费用也会小于单独在i处建立加油站.这就提示我们,可以一开始全部都建立加油站,然后从大到小依次尝试着删除加油站,如果可以删除,就删除,如果不可以,再添加上.那么该如何判断删除第i处之后是否可行呢?可以利用dfs判断,如果当前访问结点u是建立过加油站的,如果它的邻接点v也是建立了加油站的,且dist(u,v)<=d,那么

hdu 4435 第37届ACM/ICPC天津现场赛E题

转载请注明出处,谢谢http://blog.csdn.net/ACM_cxlove?viewmode=contents    by---cxlove 题目:给出N个城市,从1开始需要遍历所有点,选择一些点建立加油站,使得花费最少 这题的特殊性在于他的花费上,2^(i-1) 利用一个非常重要的性质,2^0+2^1+2^2……+2^i<2^(i+1) 所有编号<=i的所有点都建,总花费比建一个还少. 这里就贪心一下,先假设所有点都建,然后依次从编号大的删点,看看能不能遍历整个图 dist[i]表示

HDU 4435 charge-station(暴力+判图)

题目大意:给你一些点,他们可以连通,如果距离超过了d那么就要经过加油站,建立加油站的费用为第i个点是2^(i-1).求费用最小,输出二进制表示的最小费用. 费用和sum最坏等于=2^0+2^1+--+2^(n-1).所以最高位为0这个数字才会最小,从最高位暴力枚举如果删掉这个点之后图是连通的那么就可以删掉,否则不可以. 求图是否连通的时候可以爆搜求解,也可以并查集. charge-station Time Limit: 2000/1000 MS (Java/Others)    Memory L

HDU 4435 charge-station (并查集)

先说下题目的意思: 在一个二维坐标系中有N个点,某人要来个走遍所有点的旅行,但是他的车每次加油后只能走M个单位距离:所以要在这个N点中选一些建立加油站:问题来了:i^th  点 建加油站的花费是  2^(i-1); 求最小话费 用二进制表示:(其中1号必须建立加油站) 思路:有  10000>01111: 所以我们可以一开始都给这些个点染色(都建立加油站),然后从高位枚举这一位可以不建立加油站么?可以的话给他去除掉:依次类推:这样就可以维护这个“最小”: 解法:上述思路的关键是给定一个染色方案如

HDU 6203 ping ping ping [LCA,贪心,DFS序,BIT(树状数组)]

题目链接:[http://acm.hdu.edu.cn/showproblem.php?pid=6203] 题意 :给出一棵树,如果(a,b)路径上有坏点,那么(a,b)之间不联通,给出一些不联通的点对,然后判断最少有多少个坏点. 题解 :求每个点对的LCA,然后根据LCA的深度排序.从LCA最深的点对开始,如果a或者b点已经有点被标记了,那么continue,否者标记(a,b)LCA的子树每个顶点加1. #include<Bits/stdc++.h> using namespace std;

HDU 5542 The Battle of Chibi dp+树状数组

题目:http://acm.hdu.edu.cn/showproblem.php?pid=5542 题意:给你n个数,求其中上升子序列长度为m的个数 可以考虑用dp[i][j]表示以a[i]结尾的长度为j的上升子序列有多少 裸的dp是o(n2m) 所以需要优化 我们可以发现dp的第3维是找比它小的数,那么就可以用树状数组来找 这样就可以降低复杂度 #include<iostream> #include<cstdio> #include<cstring> #include

hdu 1207 汉诺塔II (DP+递推)

汉诺塔II Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 4529    Accepted Submission(s): 2231 Problem Description 经典的汉诺塔问题经常作为一个递归的经典例题存在.可能有人并不知道汉诺塔问题的典故.汉诺塔来源于印度传说的一个故事,上帝创造世界时作了三根金刚石柱子,在一根柱子上从下往