poj2728 Desert King

还比较好做的题,直接01分数规划二分答案即可,n小完全图用prim

然而

cnmd

double不可以用memset初始化我透

#include<cstdio>
#include<iostream>
#include<cmath>
#include<cstring>
#include <algorithm>
using namespace std;
const int N=1007;
const double eps=1e-6;
struct city{
    int x,y,v;
}c[N];
double rr[N][N],cost[N][N],a[N][N],mid,d[N],ans,l,r;
int n;
bool v[N];
double len(int x,int y){
    return sqrt((c[x].x-c[y].x)*(c[x].x-c[y].x)+(c[x].y-c[y].y)*(c[x].y-c[y].y));
}
int main(){
    //freopen("in","r",stdin);
    //freopen("out.out","w",stdout);
    while(1){
        double num=0.0;
        scanf("%d",&n);
        if(n==0)break;
        for(int i=1;i<=n;i++){
            scanf("%d%d%d",&c[i].x,&c[i].y,&c[i].v);
        }
        for(int i=1;i<=n;i++)
            for(int j=i;j<=n;j++){
                rr[j][i]=rr[i][j]=len(i,j);
                num+=(cost[i][j]=cost[j][i]=abs(c[i].v-c[j].v));
            }
        l=0.0,r=100;
        while(l+eps<=r){
            mid=(l+r)/2;
            ans=0;
            for(int i=1;i<=n;i++)
                for(int j=i;j<=n;j++){
                    if(i==j)a[i][j]=0x3f3f3f3f;
                    else a[i][j]=a[j][i]=cost[i][j]-mid*rr[i][j];
                }
            for (int i = 1; i <= n; i++) d[i] =0x3f3f3f3f;
                memset(v,0,sizeof(v));
                d[1]=0;
                while(1){
                    int x=0;
                    for(int j=1;j<=n;j++)
                        if(!v[j]&&(x==0||d[j]<d[x]))x=j;
                    if(!x)break;
                    v[x]=1;
                    ans+=d[x];
                    for(int y=1;y<=n;y++)
                        d[y]=min(d[y],a[x][y]);
                }
            if(ans>=0)l=mid;
            else r=mid;
        }
        printf("%.3f
",l);
    }
    return 0;
}
原文地址:https://www.cnblogs.com/Hikigaya/p/10884360.html