好蛋疼啊,由于double 不能用memset,害的我调了一个多小时才发现。由于用二分搜索,时间有点大
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <iostream>
#define maxn 1005
using namespace std;
const int INF = 0x3f3f3f;
struct node{
int x,y,z;
}Node[maxn];
double d[maxn];
double G[maxn][maxn];
double cost[maxn][maxn];
double benefit[maxn][maxn];
int n;
double mid,ans;
void calculate(int i,int j){
cost[i][j] = cost[j][i] = abs(Node[i].z - Node[j].z);
int x1=Node[i].x, y1=Node[i].y;
int x2=Node[j].x, y2=Node[j].y;
benefit[i][j] = benefit[j][i] = sqrt(1.0*(x1-x2)*(x1-x2) + 1.0*(y1-y2)*(y1-y2));
}
void makemap(){
for(int i=1;i<=n;i++)
for(int j=i+1;j<=n;j++){
G[i][j] = G[j][i] = cost[i][j] - mid * benefit[i][j];
}
return;
}
void prim(){
bool vis[maxn];
double mindist;
double lowdist[maxn];
memset(vis,0,sizeof(vis));
for(int i=1;i<=n;i++) lowdist[i] = INF;
int point;
ans = 0.0;
int s=1;
int num=1;
while(true){
if(num == n) break;
vis[s] = true;
mindist = INF;
for(int i=1;i<=n;i++){
if(!vis[i] && lowdist[i] > G[s][i]){
lowdist[i] = G[s][i];
}
if(!vis[i] && lowdist[i] < mindist){
mindist = lowdist[i];
point = i;
}
}
s = point;
ans += mindist;
num++;
}
return;
}
int main()
{
//if(freopen("input.txt","r",stdin)== NULL) {printf("Error\n"); exit(0);}
while(cin>>n && n){
for(int i=1;i<=n;i++){
cin>>Node[i].x>>Node[i].y>>Node[i].z;
}
for(int i=1;i<=n;i++)
for(int j=i+1;j<=n;j++){
calculate(i,j);
}
double R=10000000,L=0.0;
while( (R-L)>1e-6 ){
mid = (R+L)/2;
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++){
G[i][j] = INF;
}
makemap();
prim();
if(ans >= 0) L = mid;
else R = mid;
}
printf("%.3lf\n",L);
}
return 0;
}
还是迭代好上面的用时2500多MS,而这个只要297MS,空间复杂度是降不下来了。
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <iostream>
#define maxn 1005
using namespace std;
const int INF = 0x3f3f3f;
struct node{
int x,y,z;
}Node[maxn];
double d[maxn];
double G[maxn][maxn];
double cost[maxn][maxn];
double benefit[maxn][maxn];
int n;
double mid,ans;
void calculate(int i,int j){
cost[i][j] = cost[j][i] = abs(Node[i].z - Node[j].z);
int x1=Node[i].x, y1=Node[i].y;
int x2=Node[j].x, y2=Node[j].y;
benefit[i][j] = benefit[j][i] = sqrt(1.0*(x1-x2)*(x1-x2) + 1.0*(y1-y2)*(y1-y2));
}
void makemap(){
for(int i=1;i<=n;i++)
for(int j=i+1;j<=n;j++){
G[i][j] = G[j][i] = cost[i][j] - mid * benefit[i][j];
}
return;
}
void prim(){
bool vis[maxn];
double mindist;
struct low{
double lowdist;
int s;
}L[maxn];
memset(vis,0,sizeof(vis));
for(int i=1;i<=n;i++) L[i].lowdist = INF;
int point;
ans = 0.0;
int s=1;
int num=1;
double suma = 0.0,sumb = 0.0;
while(true){
if(num == n) break;
vis[s] = true;
mindist = INF;
for(int i=1;i<=n;i++){
if(!vis[i] && L[i].lowdist > G[s][i]){
L[i].lowdist = G[s][i];
L[i].s = s;
}
if(!vis[i] && L[i].lowdist < mindist){
mindist = L[i].lowdist;
point = i;
}
}
int a = L[point].s;
suma += cost[a][point];
sumb += benefit[a][point];
s = point;
num++;
}
ans = suma/sumb;
return;
}
int main()
{
//if(freopen("input.txt","r",stdin)== NULL) {printf("Error\n"); exit(0);}
while(cin>>n && n){
for(int i=1;i<=n;i++){
cin>>Node[i].x>>Node[i].y>>Node[i].z;
}
for(int i=1;i<=n;i++)
for(int j=i+1;j<=n;j++){
calculate(i,j);
}
mid = 0.5;
while( true){
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++){
G[i][j] = INF;
}
makemap();
prim();
if(abs(ans -mid) < 1e-6) break;
else mid = ans;
}
printf("%.3lf\n",ans);
}
return 0;
}