問題描述
受大西線調水工程啓發,小明也準備設計一條調水的水渠。
小明經費有限,他只能在一塊有限區域內建立一條簡單的水渠。
小明首先勘探了地形,在這塊地中有一處水源,必須用作水渠的起點。另外,小明還測量了一些點,包括點的位置和高度。如果兩個小明測量的點之間的距離不超過 d 且高度不同,小明就可以在這兩點之間建立一段水渠,讓水從高處流向低處,這一段的長度爲兩點之間的直線距離(即將橫座標的差的平方加上縱座標的差的平方加上高度差的平方後再開平方根)。
小明計劃只修一條主水渠,不建立分支的水渠。由於水渠能影響的範圍與水渠的長度正相關,小明希望水渠儘可能長。
請注意,水渠必須從水源開始修,並且高度應當遞減。水渠的不同段可能交叉(建個橋即可)。
輸入格式
輸入的第一行包含一個整數 n ,表示小明已經測量的點數。
接下來 n 行,每行三個整數 x, y, h,分別表示測量的點座標爲 (x, y),高度爲 h。這部分的第一個點即爲水源,第一個點的h值大於其他點的h值。
接下來一行包含一個整數 d。
輸出格式
輸出一行,包含一個實數,四捨五入保留 2 位小數,表示水渠最長能修多長。
樣例輸入
5
1 1 10
2 3 8
4 5 9
1 2 5
4 5 5
8
樣例輸出
10.66
樣例說明
在這些點中有兩個座標爲 (4, 5) 的點,這是允許的。
評測用例規模與約定
對於 30% 的評測用例,1 <= n <= 10;
對於 60% 的評測用例,1 <= n <= 20;
對於所有評測用例,1 <= n <= 1000,0 <= h <= 10000,0 <= x, y <= 10000,0 < d < 1e7(10的7次方)。
#include<bits/stdc++.h>
using namespace std;
#define maxn 1000
#define eps 1e-8
struct node{
int x,y,h;
};
node water[maxn];
int vis[maxn];
int cnt,n,d;
double ans,max_ans;
void add_node(int x,int y,int h){
water[cnt].x=x;water[cnt].y=y;water[cnt].h=h;
cnt++;
}
bool cmp(node a,node b){
return a.h>b.h;
}
void dfs(int t,int step){
if(step>=n-1) return;
for(int i=t+1;i<n;i++){//到往高度比t小的點
if(water[i].h>=water[t].h) break;
double dis=sqrt((water[t].x-water[i].x)*(water[t].x-water[i].x)+(water[t].y-water[i].y)*(water[t].y-water[i].y));
//cout<<d<<" "<<dis<<endl;
if(((d-dis>=eps)||(d-dis)<=eps) &&(!vis[i])){
vis[i]=1;
ans+=dis;
max_ans=max(ans,max_ans);
dfs(i,step+1);
vis[i]=0;
ans-=dis;
}
}
}
int main(){
int x,y,h;//都爲整數
cin>>n;
cnt=0;
for(int i=0;i<n;i++){
cin>>x>>y>>h;
add_node(x,y,h);
}
cin>>d;
sort(water,water+n,cmp);//高度從高到低
max_ans=ans=0;
memset(vis,0,sizeof(vis));
vis[0]=1;
dfs(0,0);//從起點開始走
printf("%.2lf\n",max_ans);
return 0;
}
/*
2
1 1 9
4 5 3
5
*/