HDU-4081-Qin Shi Huang's National Road System(次小生成树)

Input
The first line contains an integer t meaning that there are t test cases(t <= 10).
For each test case:
The first line is an integer n meaning that there are n cities(2 < n <= 1000).
Then n lines follow. Each line contains three integers X, Y and P ( 0 <= X, Y <= 1000, 0 < P < 100000). (X, Y) is the coordinate of a city and P is the population of that city.
It is guaranteed that each city has a distinct location.
 

Output
For each test case, print a line indicating the above mentioned maximum ratio A/B. The result should be rounded to 2 digits after decimal point.
 

Sample Input
   
   
   
   
2 4 1 1 20 1 2 30 200 2 80 200 1 100 3 1 1 20 1 2 30 2 2 40
 

Sample Output
   
   
   
   
65.00 70.00
 

Source
2011 Asia Beijing Regional Contest 



坐标系各点带权,求关于各点距离的最小生成树后,遍历所有边找满足题意的A/B,

即,

uv不属于MST时    A/B=max(A/B,(people(u)+people(v))/(ans-MAX[u][v]))    

uv属于MST时        A/B=max(A/B,people(u)+people(v))/(ans-cost[u][v])




//#pragma comment(linker, "/STACK:1024000000,1024000000")
#include <iostream>
#include <cstdio>
#include <cmath>
#include <vector>
#include <cstring>
#include <algorithm>
#include <string>
#include <set>
#include <stack>
#include <map>
#include <queue>
#define INF 0x3f3f3f3f
using namespace std;
const int MAXN = 1005;
double cost[MAXN][MAXN];
bool vis[MAXN];
bool in_MST[MAXN][MAXN];
double Max_e[MAXN][MAXN];
double lowcost[MAXN];
int pre[MAXN];
int m,n;
struct Point
{
    int x,y;
    int popu;
} point[MAXN];
double Distance(Point a,Point b)
{
    return sqrt((double)((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y)));
}
double prim()
{
    double ans=0;
    memset(vis,0,sizeof(vis));
    memset(Max_e,0,sizeof(Max_e));
    memset(in_MST,0,sizeof(in_MST));
    vis[0]=1;
    pre[0]=-1;
    for(int i=0; i<n; ++i)
    {
        lowcost[i]=cost[0][i];
        pre[i]=0;
    }
    lowcost[0]=0;
    for(int i=1; i<n; ++i)
    {
        double minc=INF;
        int p=-1;
        for(int j=0; j<n; ++j)
            if(!vis[j] && minc>lowcost[j])
            {
                minc=lowcost[j];
                p=j;
            }
        if(minc==INF)return -1;
        ans+=minc;
        vis[p]=true;
        in_MST[p][ pre[p] ]=in_MST[ pre[p] ][p]=true;
        for(int j=0; j<n; ++j)
        {
            if(vis[j] && j!=p)
                Max_e[j][p]=Max_e[p][j]=max(Max_e[pre[p]][j],lowcost[p]);
            if(!vis[j]&&lowcost[j]>cost[p][j])
            {
                lowcost[j]=cost[p][j];
                pre[j]=p;
            }
        }
    }
    return ans;
}
int main()
{
    int T;
    scanf("%d",&T);
    while(T--)
    {
        scanf("%d",&n);
        for(int i=0; i<n; ++i)cost[i][i]=0;
        for(int i=0; i<n; ++i)
        {
            scanf("%d%d%d",&point[i].x,&point[i].y,&point[i].popu);
            for(int j=0; j<i; ++j)
                cost[i][j]=cost[j][i]=Distance(point[i],point[j]);
        }
        double ans=prim(),temp;
        double Max=0;
        for(int i=0; i<n; ++i)
            for(int j=i+1; j<n; ++j)
            {
                double peo=point[i].popu+point[j].popu;
                if(in_MST[i][j])
                {
                    temp=peo/(ans-cost[i][j]);
                    if(temp>Max)
                        Max=temp;
                }
                else
                {
                    temp=peo/(ans-Max_e[i][j]);
                    if(temp>Max)
                        Max=temp;
                }
            }
        printf("%0.2lf\n",Max);
    }
    return 0;
}



你可能感兴趣的:(C++,ACM,HDU)