hdu 4435 charge-station

// 题意 从1出发逛完N个点回到出发点 要在这N个点选择性建设加油站 车每次加满油最多可以行使D米
// 然后最少要花多少钱才能达到上述要求
// 注意到 第i个城市的花费是 2^(i-1) 所以 我就从N枚举到2
// 尽量让 i大的不建加油站 应为前i-1个加油站总费用都没有第i个加油站一个的费用多
// 难点是怎么判断一组方案的可行性
// 注意到 若i 不建加油站 那么必须存在某个加油站和他距离等于小于 (D+1)/2
// 这样对于每组方案进行搜索,看下是否每个点都是可以达到并可以回到起点的
//
#include <iostream> #include <stdio.h> #include <string.h> #include <cmath> using namespace std; #define INF 100000000 bool mark[200]; int dis[200][200]; int N,D; double sq(double x1,double y1,double x2,double y2){ return (x1-x2)*(x1-x2)+(y1-y2)*(y1-y2); } bool visit[150]; int ct; void dfs(int u){// 判断有无解
visit[u]
=true; ct++; for(int i=1;i<=N;i++) if(!visit[i]&&dis[u][i]<=D){ dfs(i); } } void OK(int u,int lt){// 判断方案的可行性
if(mark[u]){ lt=D,visit[u]=true; ct++; } else{ if(lt>=(D+1)/2) visit[u]=true,ct++; else return; } for(int i=1;i<=N;i++) if(u!=i&&!visit[i]&&dis[u][i]<=lt) OK(i,lt-dis[u][i]); } int main(){ int rc[200][2]; int i,j; while(scanf("%d %d",&N,&D)!=EOF){ for(i=1;i<=N;i++) mark[i]=true; for(i=1;i<=N;i++) scanf("%d %d",&rc[i][0],&rc[i][1]); if(N==1){printf("0\n");continue;} for(i=1;i<N;i++) for(j=i+1;j<=N;j++){ double t=sq(rc[i][0],rc[i][1],rc[j][0],rc[j][1]); int ti=ceil(sqrt(t)); dis[i][j]=dis[j][i]=ti; } memset(visit,0,sizeof(visit)); ct=0; dfs(1); if(ct<N) {printf("-1\n");continue;} for(i=N;i>1;i--){ // 枚举方案
mark[i]
=false; ct=0; memset(visit,0,sizeof(visit)); OK(1,0); if(ct<N) mark[i]=true; } for(i=N;i>0;i--)if(mark[i]) break; for(;i>0;i--) if(mark[i])printf("1");else printf("0"); printf("\n"); } return 0; }

 

posted on 2013-08-02 15:20  江财小子  阅读(190)  评论(0编辑  收藏  举报