HDU_4081

    这个题目大体的思路是这个样子的,首先求一个最小生成树,然后求出或者顺便求出最小生成树上任意两点间路径上的最大边权,之后枚举magic road,把magic road两个端点间的之前记录的最大边边权减去后作为B,把magic road两个端点上的人口和作为A,更新一下A/B即可。

#include<stdio.h>
#include<string.h>
#include<math.h>
#include<stdlib.h>
#define MAXD 1010
#define MAXM 1000010
int N, x[MAXD], y[MAXD], people[MAXD], a[MAXM], b[MAXM], M, e, r[MAXM];
int first[MAXD], next[2 * MAXD], v[2 * MAXD], vis[MAXD], p[MAXD];
double w[MAXM], maxlen[MAXD][MAXD], total, len[2 * MAXD];
int cmp(const void *_p, const void *_q)
{
int *p = (int *)_p;
int *q = (int *)_q;
return w[*p] < w[*q] ? -1 : 1;
}
int find(int x)
{
return p[x] == x ? x : (p[x] = find(p[x]));
}
double distance(int i, int j)
{
return sqrt((double)(x[i] - x[j]) * (x[i] - x[j]) + (y[i] - y[j]) * (y[i] - y[j]));
}
void init()
{
int i, j;
scanf("%d", &N);
for(i = 0; i < N; i ++)
scanf("%d%d%d", &x[i], &y[i], &people[i]);
M = 0;
for(i = 0; i < N; i ++)
for(j = i + 1; j < N; j ++)
{
a[M] = i;
b[M] = j;
w[M] = distance(i, j);
M ++;
}
}
void add(int x, int y, double z)
{
v[e] = y;
len[e] = z;
next[e] = first[x];
first[x] = e;
e ++;
}
void dfs(int fa, int cur, double max)
{
int i;
vis[cur] = 1;
for(i = first[cur]; i != -1; i = next[i])
if(!vis[v[i]])
{
if(len[i] > max)
{
maxlen[fa][v[i]] = len[i];
dfs(fa, v[i], len[i]);
}
else
{
maxlen[fa][v[i]] = max;
dfs(fa, v[i], max);
}
}
}
void prepare()
{
int i, j, k, tx, ty;
for(i = 0; i < M; i ++)
r[i] = i;
qsort(r, M, sizeof(r[0]), cmp);
for(i = 0; i < N; i ++)
p[i] = i;
e = 0;
memset(first, -1, sizeof(first));
total = 0;
for(i = 0; i < M; i ++)
{
k = r[i];
tx = find(a[k]);
ty = find(b[k]);
if(tx != ty)
{
total += w[k];
p[tx] = ty;
add(a[k], b[k], w[k]);
add(b[k], a[k], w[k]);
}
}
for(i = 0; i < N; i ++)
{
memset(vis, 0, sizeof(vis));
dfs(i, i, 0);
}
}
void solve()
{
int i, j;
double temp, res = 0;
for(i = 0; i < N; i ++)
for(j = i + 1; j < N; j ++)
{
temp = (double)(people[i] + people[j]) / (total - maxlen[i][j]);
if(temp > res)
res = temp;
}
printf("%.2f\n", res);
}
int main()
{
int t;
scanf("%d", &t);
while(t --)
{
init();
prepare();
solve();
}
return 0;
}



posted on 2011-11-02 02:37  Staginner  阅读(754)  评论(0编辑  收藏  举报