您的位置:首页 > 其它

HDU 4435 charge-station

2012-10-28 21:25 225 查看
2012天津赛区现场赛的E题,刚才做模拟比赛的时候和安神讨论了很久,思路没理清。

大致题意是 给出N个点,让你选择性地建立加油站,在第i个点建立加油站的费用为2^i-1,要使自己能从1号点经过所有点回到原点,

点可以重复经过,加油费用不计,每次加油最多能跑的距离为D。输出的答案是2进制,由费用10进制转化过来就是在第i个点建立加

油站,答案从右往左数第i个值就为1。

第一步判断所有点都建立加油站能不能完成题目的要求,不能输出-1。

能完成要求的话,我们注意到建站费用是和点的编号有关的,比如第i个点建站的费用是等于前i-1个点都建站的费用+1,二进制的规律。

然后我们可以从后往前判断当前加油站能不能拆。

dist数组存从当前点到最近的加油站的距离,判断分两个方面:

如果当前点也有加油站,dist[i] <= D就可以;

如果当前点决定不建立加油站,那么dist[i]要小于D/2;

不符合要求就不能拆这个加油站。

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <math.h>
#include <queue>
#include <algorithm>
using std::queue;
using std::min;
const int MAXN = 130;
const int INF = 0x3f3f3f3f;

struct point
{
int x, y;
}p[MAXN];

int n, d;
int g[MAXN][MAXN], dist[MAXN], sta[MAXN];
bool vis[MAXN];

int pf(int i)
{
return i * i;
}

double distance(int i, int j)
{
return sqrt((double)(pf(p[i].x - p[j].x) + pf(p[i].y - p[j].y)));
}

void ReadGraph()
{
//让点号从0开始则每个点建立加油站的费用2^i
for(int i = 0; i < n; i ++)
{
scanf("%d%d", &p[i].x, &p[i].y);
}
for(int i = 0; i < n; i ++)
for(int j = 0; j < n; j ++)
{
g[i][j] = (int)ceil(distance(i, j));
}
}

bool judge()
{
queue<int> q;
memset(vis, false, sizeof vis);
for(int i = 0; i < n; i ++)
{
if(!sta[i]) dist[i] = INF;
else dist[i] = 0;
}
vis[0] = true;
dist[0] = 0;
q.push(0);
while(!q.empty())
{
int u = q.front();
q.pop();
for(int i = 0; i < n; i ++)
{
if(!vis[i] && g[u][i] <= d)
{
dist[i] = min(dist[i], dist[u] + g[u][i]);
if(sta[i])
{
vis[i] = true;
q.push(i);
}
}

}
}
for(int i = 0; i < n; i ++)
{
if(sta[i] && !vis[i])
return false;
else if(!sta[i] && dist[i] * 2 > d)
return false;
}
return true;
}

void solve()
{
for(int i = 0; i < n; i ++)
{
sta[i] = 1;
}
if(!judge())
{
puts("-1");
return;
}
for(int i = n - 1; i >= 1; i --)
{
sta[i] = 0;
if(judge()) continue;
sta[i] = 1;
}
int cur = n - 1;
while(!sta[cur])
cur --;
for( ; cur >= 0; cur --)
{
printf("%d", sta[cur]);
}
printf("\n");
}

int main()
{
//freopen("test.in", "r", stdin);
while(scanf("%d%d", &n, &d) != EOF)
{
ReadGraph();
solve();
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: