hdu4081Qin Shi Huang's National Road System 次小生成树

//给出每点的坐标和其到人口量,找一个生成树,其中有一条边造价为0
//问A/B的最大值,A这条边连接的两个点的人口之和
//B除了这条边以外的其他边的长度之和
//先找到最小生成树,然后枚举所有边,如果这条边是最小生成树上的边,
//直接计算A/(sum-edge) ,如果不是,那么这条边加在最小生成树上会出现一个
//环,去除这个环中的最长的边依然是一棵树,
//用dp[u][v] 表示在最小生成树中从u到v的唯一路径所经过的最长边的大小
//dp[u][v[i]] = dp[v[i]][u]= max(map[F[u]][u] , dp[F[u]][v[i]])  ;
#include<cstdio>
#include<cstring>
#include<iostream>
#include<cmath>
using namespace std ;
const int maxn = 1010 ;
const int inf = 0x3f3f3f3f ;
double dp[maxn][maxn] ;
double map[maxn][maxn] ;
double x[maxn] , y[maxn] , p[maxn] ;
int F[maxn] ;int vis[maxn] ;
int v[maxn] ;double dis[maxn] ;
int n ;
double prim()
{
    int len = 0 ;
    memset(vis ,0  ,sizeof(vis)) ;
    memset(dp , 0 , sizeof(dp)) ;
    for(int i = 2;i <=n; i++)
    dis[i] = inf  ;
    dis[1] = 0 ;F[1] = 1 ;
    v[++len] = 1 ;
    double ans = 0 ;
    while(1)
    {
        double  mi = inf ;int u ;
        for(int i = 1;i <= n;i++)
        if(!vis[i]&&dis[i] < mi)
        mi = dis[u = i] ;
        if(mi == inf)break;
        vis[u] = 1;
        ans += mi ;
        for(int i = 1;i <= len ;i++)
        dp[u][v[i]] = dp[v[i]][u]= max(map[F[u]][u] , dp[F[u]][v[i]])  ;
        v[++len] = u ;
        for(int i = 1;i <= n;i++)
        if(!vis[i] && map[u][i] < dis[i])
        {
            dis[i] = map[u][i] ;
            F[i] = u ;
        }
    }
    return ans ;
}
int main()
{
    //freopen("in.txt" ,"r" , stdin) ;
    int t ;
    scanf("%d" , &t) ;
    while(t--)
    {
        scanf("%d" , &n) ;
        for(int i = 1;i <= n;i++)
        {
            scanf("%lf%lf%lf" , &x[i] , &y[i] , &p[i]) ;
            for(int j = 1;j <= i;j++)
            map[i][j] = map[j][i] = sqrt((x[i]-x[j])*(x[i]-x[j]) + (y[i] - y[j])*(y[i]-y[j])) ;
        }
        double sum = prim() ;
        double ans = 0 ;
        for(int i = 1;i <= n;i++)
        for(int j = 1; j < i ;j++)
            ans = max(ans , (p[i] + p[j])/(sum - dp[i][j])) ;
        printf("%.2lf\n" , ans) ;
    }
    return 0 ;
}

版权声明:本文为博主原创文章,未经博主允许不得转载。

hdu4081Qin Shi Huang's National Road System 次小生成树

时间: 2025-01-18 05:37:38

hdu4081Qin Shi Huang's National Road System 次小生成树的相关文章

hdu4081 Qin Shi Huang&#39;s National Road System 次小生成树

先发发牢骚:图论500题上说这题是最小生成树+DFS,网上搜题解也有人这么做.但是其实就是次小生成树.次小生成树完全当模版题.其中有一个小细节没注意,导致我几个小时一直在找错.有了模版要会用模版,然后慢慢融会贯通.我要走的路还长着啊. 讲讲次小生成树的思想吧.首先,在prim算法中做一些改变,求出任意两点(u,v)路径之间的最大权值,并记录,记为maxe[u][v].运行遍prim算法.枚举每一条边,如果该边是属于最小生成树的边,则ratio=(value(u) +value(v) ) /( a

hdu 4081 Qin Shi Huang&#39;s National Road System 次小生成树 算法

Qin Shi Huang's National Road System Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 4180    Accepted Submission(s): 1450 Problem Description During the Warring States Period of ancient China(4

HDU 4081 Qin Shi Huang&#39;s National Road System 次小生成树

给你n个城市 每个城市有一定数量的人 连接2个城市需要的花费是他们之间的距离 现在要建一颗最小生成树 可以免费建其中一条边 设A为免费的那条边连接的2个城市的人口之和 B为修建的最小生成树的花费 求最大的A/B 先求最小生成树 设总花费为totol 然后可以枚举免费的那条边 枚举边等于A确定 在这条在最小生成树里的情况下 求最小的B 如果这条边是最小生成树里的边 那么很容易求得B 拿totol减去这条边就行了 如果不是 那么把这条边加到最小生成树 会出现一个环 找到这个环最大的那条边剪掉 就是次

HDU 4081 Qin Shi Huang&#39;s National Road System 次小生成树变种

Qin Shi Huang's National Road System Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) [Problem Description] During the Warring States Period of ancient China(476 BC to 221 BC), there were seven kingdoms in China ---

HDU4081Qin Shi Huang&#39;s National Road System(最小生成树+DFS)

Qin Shi Huang's National Road System Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 4227    Accepted Submission(s): 1465 Problem Description During the Warring States Period of ancient China(4

HDU4081 Qin Shi Huang&#39;s National Road System【Kruska】【次小生成树】

Qin Shi Huang's National Road System Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 3979    Accepted Submission(s): 1372 Problem Description During the Warring States Period of ancient China(4

HDU 4081 Qin Shi Huang&#39;s National Road System 最小生成树

分析:http://www.cnblogs.com/wally/archive/2013/02/04/2892194.html 这个题就是多一个限制,就是求包含每条边的最小生成树,这个求出原始最小生成树然后查询就好了 然后预处理那个数组是O(n^2)的,这样总时间复杂度是O(n^2+m) 这是因为这个题n比较小,如果n大的时候,就需要路径查询了,比如LCA 或者树链剖分达到O(mlogn) #include <iostream> #include <algorithm> #incl

HDU4081 Qin Shi Huang&#39;s National Road System(次小生成树)

枚举作为magic road的边,然后求出A/B. A/B得在大概O(1)的时间复杂度求出,关键是B,B是包含magic road的最小生成树. 这么求得: 先在原图求MST,边总和记为s,顺便求出MST上任意两点路径上的最长边d[i][j]. 当(u,v)是magic road时, 如果它在原本的MST上,则B就等于s-原(u,v)的权,而原(u,v)的权其实就是d[u][v]: 如果它不在原本的MST上,则B就等于s-d[u][v]+0. 总之就是一个式子:B=s-d[u][v]. 于是,在

HDU 4081 Qin Shi Huang&#39;s National Road System

https://vjudge.net/problem/HDU-4081 题意: 秦始皇想要修长城,修成生成树的样子,这是一个大师出现了,他说他可以不耗费人力修出一条路来.他们的目的很不一样,神特么有分歧,最后他们达成了一个协议,假设一个城市的人口为a.那么最后不耗费人力修的那条路所相连的两个城市的人力之和A与修路花费的人力B之比 A/B最大,并且输出最大值. 思路: 枚举去掉每一条边. 首先求出最小生成树,对于最小生成树中的每一条边,如果这条边不花费人力,那么直接计算A和B就可以了. 那么问题是