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

来源:互联网 发布:cisco 端口隔离 编辑:程序博客网 时间:2024/04/30 12:06

题目大意:有N个城市,现在要修建一些道路使得这些城市能互相连通,修建一条道路的权值为这两个城市之间的欧几里德距离。
现在你可以选择一条路作为特殊道路,这条道路的权值为0
假设修建道路的总权值为B,用特殊道路的连接的两个城市人口之和为A,问A/B的最大值

解题思路:先求出最小生成树,最小生成树的总权值肯定是最低的,在求最小生成树的期间,顺便把任意两点的之间的唯一路径的最大权值给求出来,并纪录

接着枚举修建特殊道路的两个城市,两个城市的连线有可能在最小生成树内形成一个环,这时候就要剔除掉这个环内的最大权值了,前面用到的记录就有用了

#include <cstdio>#include <cstring>#include <cmath>#include <vector>#include <algorithm>using namespace std;#define N 1010const double INF = 1e9;int x[N], y[N], p[N], f[N];int n;double dis[N][N], d[N], maxcost[N][N];bool vis[N];vector<int> v;double distance(int i, int j) {    int x1 = x[i] - x[j];    int y1 = y[i] - y[j];    return sqrt(1.0 * x1 * x1 + 1.0 * y1 * y1);}void init() {    scanf("%d", &n);    for (int i = 1; i <= n; i++) {        scanf("%d%d%d", &x[i], &y[i], &p[i]);        dis[i][i] = 0;        for (int j = 1; j <= i - 1; j++)            dis[i][j] = dis[j][i] = distance(i, j);    }}double prim() {    v.clear();    double B = 0;    memset(vis, 0, sizeof(vis));    for (int i = 1; i <= n; i++)        d[i] = INF;    d[1] = 0;    f[1] = 1;    for (int i = 1; i <= n; i++) {        int x;        double t = INF;        for (int j = 1; j <= n; j++)            if (!vis[j] && d[j] < t)                 t = d[x = j];        vis[x] = true;        B += dis[f[x]][x];        int size = v.size();        for (int j = 0; j < size; j++) {            maxcost[v[j]][x] = maxcost[x][v[j]] = max(maxcost[v[j]][f[x]], dis[f[x]][x]);        }        v.push_back(x);        for (int j = 1; j <= n; j++)            if (!vis[j] && dis[x][j] < d[j]) {                d[j] = dis[x][j];                f[j] = x;            }    }    return B;}void solve() {    double B = prim();    double ans = 0;    for (int i = 1; i <= n; i++)        for (int j = i + 1; j <= n; j++)            ans = max(ans, (p[i] + p[j]) * 1.0 / (B - maxcost[i][j]));    printf("%.2lf\n", ans);}int main() {    int test;    scanf("%d", &test);    while (test--) {        init();        solve();    }    return 0;}
0 0
原创粉丝点击