POJ 2728 Desert King 最优比率生成树(分数规划+Prim)

POJ 2728 Desert King 最优比率生成树(分数规划+Prim)

这题好题啊,网上也有很多解题报告的呢,哥也是看了才懂写的。。
直接贴代码。这个代码不咋地呢。
分数规划用迭代法500+ms,用二分法就2000+ms了。可见差异还是挺大的,还是迭代法好。
膜拜下分数规划算法的创始人

#include  < stdio.h >
#include 
< math.h >
#include 
< string .h >

int  X[ 1024 ], Y[ 1024 ], Z[ 1024 ], N, from[ 1024 ];
char  mst[ 1024 ];
double  D[ 1024 ], rate;
struct   {
    
double w, cost, len;
}
 E[ 1024 ][ 1024 ];

double  prim( double  L)
{
    
int i, j;
    
double res, cost, len;

    
for (i = 0; i < N; i++)
        
for (j = i; j < N; j++
            E[i][j].w 
= E[j][i].w = E[i][j].cost - E[i][j].len * L;

    
for (i = 0; i < N; i++{
        D[i] 
= E[0][i].w;
        from[i] 
= 0;
    }

    memset(mst, 
0, N);
    mst[
0= 1;

    res 
= cost = len = 0;
    
for (i = 0; i < N - 1; i++{
        
double min_d;
        
int min_i;

        min_d 
= 1e50;
        
for (j = 0; j < N; j++{
            
if (!mst[j] && D[j] < min_d) {
                min_d 
= D[j];
                min_i 
= j;
            }

        }


        mst[min_i] 
= 1;
        res 
+= min_d;
        cost 
+= E[min_i][from[min_i]].cost;
        len 
+= E[min_i][from[min_i]].len;

        
for (j = 0; j < N; j++{
            
if (!mst[j] && E[min_i][j].w < D[j]) {
                D[j] 
= E[min_i][j].w;
                from[j] 
= min_i;
            }

        }

    }


    rate 
= cost / len;
    
return res;
}



void  solve()
{
/**//*
    double l, r, m;

    l = 0;
    r = 1000;
    while (r - l > 0.0001) {
        m = (r + l) / 2;
        if (prim(m) > 0)
            l = m;
        else
            r = m;
    }
*/

    
double r;
    
int i, j;

    
for (i = 0; i < N; i++{
        
for (j = i; j < N; j++{
            
double dx, dy;
            dx 
= (double)X[i] - X[j];
            dy 
= (double)Y[i] - Y[j];
            E[i][j].cost 
= E[j][i].cost = fabs((double)Z[i] - Z[j]);
            E[i][j].len 
= E[j][i].len = sqrt(dx*dx + dy*dy);
        }

    }


    rate 
= 0;
    
do {
        r 
= rate;
        prim(rate);
    }
 while (fabs(r - rate) > 0.0001);

    printf(
"%.3f\n", rate);
}


int  main()
{
    
int i;

    freopen(
"e:\\test\\in.txt""r", stdin);

    
while (1{
        scanf(
"%d"&N);
        
if (!N)
            
break;
        
for (i = 0; i < N; i++
            scanf(
"%d%d%d"&X[i], &Y[i], &Z[i]);
        solve();
    }

    
return 0;
}

你可能感兴趣的:(POJ 2728 Desert King 最优比率生成树(分数规划+Prim))