hdu4435 搜索加贪心

题意:

就是给出n个城市的坐标,一辆车从1出发,能达到所有的点,并且能范围到1.一辆车加满油能开的距离为D,在第i个城市建油站的费用为2^(i-1).

求最小花费。

题解:在第i个城市建造花费比前i-1个都建造花费都大,所以先全部假设建加油站,依次从最后一个枚举假设不建加油站能否到达

判断是否可以到达只要判断加油站之间距离小于等于d,加油站与非加油站距离小于等于d/2,

然后光搜就好了,,,因为对于非加油站,必定是回到加油站才是最优方案

 1 #include <cstdio>
 2 #include <cstring>
 3 #include <vector>
 4 #include <algorithm>
 5 #include <iostream>
 6 #include <map>
 7 #include <queue>
 8 #include <stack>
 9 #include <cmath>
10 //#pragma comment(linker, "/STACK:102400000,102400000")
11 using namespace std;
12 #define PF(x) cout << "debug: " << x << " ";
13 #define EL cout << endl;
14 #define PC(x) puts(x);
15 typedef long long ll;
16 #define CLR(x, v) sizeof (x, v, sizeof(x))
17 using namespace std;
18 const int INF = 0x5f5f5f5f;
19 const int  N= 2e5 + 10;
20 const int mod=1e9 + 7;
21 const int maxn = 150;
22 int n,d,gra[maxn][maxn],a[maxn][2],ans[maxn];
23 int getjuli(int i,int j){
24     double sum = sqrt((a[i][0] - a[j][0])*(a[i][0] - a[j][0]) + (a[i][1] - a[j][1]) * (a[i][1] - a[j][1]));
25     if(sum == (int)sum)
26         return (int)sum;
27     else
28         return (int)sum + 1;
29 }
30 bool bfs(int u){
31     queue<int>q;
32     q.push(1);
33     bool fg[150];
34     memset(fg,false,sizeof(fg));
35     fg[1] = true;
36     while(!q.empty()){
37         int v = q.front();
38         q.pop();
39         for(int i = 1;i <= n;i++){
40             if(fg[i]) continue;
41             if(ans[i]&&gra[v][i] <= d&&!fg[i]){
42                 fg[i] = true;
43                 q.push(i);
44             }
45             if(!ans[i]&&gra[v][i] <= d/2&&!fg[i]){
46                 fg[i] = true;
47             }
48         }
49     }
50     int i;
51     for(i = 1;i <= n;i++) if(!fg[i]) break;
52     if(i > n) return true;
53     else return false;
54 
55 }
56 int main()
57 {
58     //freopen("in.txt","r",stdin);
59     while(~scanf("%d%d",&n,&d)){
60         memset(ans,1,sizeof(ans));
61         for(int i = 1;i <= n;i++)
62         scanf("%d%d",&a[i][0],&a[i][1]);
63         for(int i = 1;i <= n;i++)
64             for(int j = i;j <= n;j++){
65             gra[i][j] = getjuli(i,j);
66             gra[j][i] = gra[i][j];
67     }
68         if(!bfs(1)){
69             cout<<-1<<endl;
70             continue;
71         }
72         for(int i = n;i >= 2;i--){
73             ans[i] = 0;
74             if(!bfs(1))
75                 ans[i] = 1;
76         }
77         int fg = 0;
78         for(int i = n;i >= 1;i--){
79             if(ans[i] == 0){
80                 if(!fg)
81                     continue;
82                 else
83                     cout<<0;
84             }
85             else{
86                 fg = 1;
87                 cout<<1;
88             }
89         }
90         cout<<endl;
91     }
92     return 0;
93 }

 

转载于:https://www.cnblogs.com/shimu/p/5821690.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值