uvaLive5713

修建道路使得n个点任意两点之间都可以连通,每个点有都有一定的人口,现在可以免费修一条道路,

A是免费修的道路两端结点的人口之和, B的其它不是免费修道路的长度的总和

要求的是A/B的最短值。

B其实就是最小生成树删除一条边只有的权值之和B。 只要我们知道生成树上任意两点之间的最长边,那么只要在这两点之间修一条边,

然后删除最长边,它还是一棵树。 而已这时候的权值之和是B-maxCost[u][v]

那么 答案就是min{p[u][v] / (B-maxCost[u][v])} , 枚举u,v的时间复杂度是O(n*n)。

至于得到maxCost[u][v] 只要在得到最小生成树之后,一遍dfs就可以求出

求解的方法是:当访问一个新节点时,计算所有已经访问过的结点到这个结点的最小权值

max[u][x] = maxCost[x][u] = max(maxCost[x][fa],edge(u,fa))

u是当前访问的结点,fa是u的父亲, x是所有已经访问过的结点。

(其实就是两个嵌套的循环,只不过是在树上循环罢了)

总的时间复杂度是n*n + e*loge     常数没有计算进去。

n*n和eloge 最大时都是1000多w, 3s的时间,足够了

 #include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <algorithm>
#include <iostream>
#include <queue>
#include <stack>
#include <vector>
#include <map>
#include <set>
#include <string>
#include <math.h>
using namespace std;
#pragma warning(disable:4996)
#pragma comment(linker, "/STACK:1024000000,1024000000")
typedef long long LL;
const int INF = <<;
/* */
const int N = + ;
struct Edge
{
int form, to, p;
double dist;
bool operator<(const Edge&rhs)const
{
return dist < rhs.dist;
}
}a[N*N];
int x[N], y[N], p[N];
int father[N];
double maxCost[N][N];
int p2[N][N];
vector<Edge> g[N];
vector<int> st;
int find(int x)
{
if (x == father[x])
return x;
return father[x] = find(father[x]);
}
double kruskal(int n)
{
double sum = ;
for (int i = ; i < n; ++i)
{
int fx = find(a[i].form);
int fy = find(a[i].to);
if (fx != fy)
{
//记录生成树,用来等下dfs
g[a[i].form].push_back(a[i]);
swap(a[i].form, a[i].to);
g[a[i].form].push_back(a[i]);
sum += a[i].dist;
father[fx] = fy;
}
}
return sum;
} /*
这个dfs其实就是给定一棵树,然后求任意两点之间的最大边权, 因为是任意两点, 那么时间复杂度无疑就是O(n*n)
*/
void dfs(int u, int fa, double dis)
{
if (fa!=-)
for (int i = ; i < st.size(); ++i)
{
int x = st[i];
maxCost[x][u] = maxCost[u][x] = max(maxCost[x][fa], dis);
}
st.push_back(u);
for (int i = ; i < g[u].size(); ++i)
{
int v = g[u][i].to;
if (v == fa) continue;
dfs(v, u, g[u][i].dist);
}
}
int main()
{
int t, n, cnt;
double B;
scanf("%d", &t);
while (t--)
{
scanf("%d", &n);
cnt = ;
st.clear();
for (int i = ; i < n; ++i)
{
father[i] = i;
g[i].clear();
scanf("%d%d%d", &x[i], &y[i], &p[i]);
}
for (int i = ; i < n; ++i)
{
for (int j = i + ; j < n; ++j)
{
p2[i][j] = p2[j][i] = p[i] + p[j];
//边集数组
a[cnt].form = i;
a[cnt].to = j;
a[cnt].p = p[i] + p[j];
a[cnt++].dist = sqrt((x[i] - x[j])*(x[i] - x[j]) + (y[i] - y[j])*(y[i] - y[j]));
}
}
sort(a, a + cnt);
B = kruskal(cnt);
dfs(, -, );
double ans = ; //枚举在哪两个之间建免费的道路
for (int i = ; i < n; ++i)
for (int j = i + ; j < n; ++j)
ans = max(ans, p2[i][j] / (B - maxCost[i][j]));
printf("%.2lf\n", ans);
}
return ;
}

uvaLive5713 次小生成树的更多相关文章

  1. UVALive-5713 Qin Shi Huang's National Road System (次小生成树)

    题目大意:有n个城市,要修一些路使得任意两个城市都能连通.但是有人答应可以不计成本的帮你修一条路,为了使成本最低,你要慎重选择修哪一条路.假设其余的道路长度为B,那条别人帮忙修的道路两端城市中的总人口 ...

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

    题目大意: 有n个城市,秦始皇要修用n-1条路把它们连起来,要求从任一点出发,都可以到达其它的任意点.秦始皇希望这所有n-1条路长度之和最短.然后徐福突然有冒出来,说是他有魔法,可以不用人力.财力就变 ...

  3. POJ1679 The Unique MST[次小生成树]

    The Unique MST Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 28673   Accepted: 10239 ...

  4. The Unique MST(次小生成树)

    Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 22335   Accepted: 7922 Description Give ...

  5. URAL 1416 Confidential --最小生成树与次小生成树

    题意:求一幅无向图的最小生成树与最小生成树,不存在输出-1 解法:用Kruskal求最小生成树,标记用过的边.求次小生成树时,依次枚举用过的边,将其去除后再求最小生成树,得出所有情况下的最小的生成树就 ...

  6. POJ1679The Unique MST(次小生成树)

    The Unique MST Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 25203   Accepted: 8995 D ...

  7. [kuangbin带你飞]专题八 生成树 - 次小生成树部分

    百度了好多自学到了次小生成树 理解后其实也很简单 求最小生成树的办法目前遇到了两种 1 prim 记录下两点之间连线中的最长段 F[i][k] 之后枚举两点 若两点之间存在没有在最小生成树中的边 那么 ...

  8. URAL 1416 Confidential(次小生成树)

    题目链接:http://acm.timus.ru/problem.aspx?space=1&num=1416 Zaphod Beeblebrox — President of the Impe ...

  9. ACM题目————次小生成树

    Description 最小生成树大家都已经很了解,次小生成树就是图中构成的树的权值和第二小的树,此值也可能等于最小生成树的权值和,你的任务就是设计一个算法计算图的最小生成树. Input 存在多组数 ...

随机推荐

  1. UVA11090 Going in Cycle!! (二分+SPFA推断有无负权)

    Problem G: Going in Cycle!! Input: standard input Output: standard output You are given a weighted d ...

  2. 忽然想到:把Mu的源代码一网打尽

    那么那些流媒体开发的公司,就不会拒绝我了,真是一举两得.

  3. COCOS2D中对精灵的操作、对图片的各种操作

    内容简要: 1.初始化 2.创建无图的精灵 3.设置精灵贴图大小  4.添加入层中 5.对精灵进行缩放  6.对精灵宽或高进行缩放  7.旋转精灵 8.设置精灵透明度  9.精灵的镜像反转  10.设 ...

  4. C#整理

    输入输出--数据类型--变量与常量--运算符表达式--语句(顺序.分支.循环)--数组--函数--结构体一.输入与输出.Console.ReadLine();Console.WriteLine();C ...

  5. linux下安装QT过程

    说QT是linux下主要的图形开发工具一点都不过分,虽然诺基亚公司放弃Meego.遣散了Qt开发团队,但是它的各种商业.企业版本还是的到了很好的保护,linux下的开发工具集里还是经常看到它的身影,毕 ...

  6. hdu 1240 Asteroids!(BFS)

    题目链接:点击链接 简单BFS,和二维的做法相同(需注意坐标) 题目大意:三维的空间里,给出起点和终点,“O”表示能走,“X”表示不能走,计算最少的步数 #include <iostream&g ...

  7. Conexant声卡实现内录功能(win7)

    Conexant声卡本身没有立体声混音设备可选,所以我们采用virtual audio device,实现内录功能. [1]下载virtual audio device.下载地址:http://dow ...

  8. Qt笔记——MOC(莫克)

    moc 代表 Meta-Object Compiler,"元对象编译器".Qt 程序在交由标准编译器编译之前,先要使用 moc 分析 C++ 源文件. 假设它发如今一个头文件里包括 ...

  9. C#获取Excel中所有的Sheet名称

    原文地址:http://blog.csdn.net/qq1010726055/article/details/6858849 Excel.Application myExcel = new Excel ...

  10. linux常用系统配置命令汇总

    系统配置及查看信息相关命令 # uname -a # 查看内核/操作系统/CPU信息# head -n 1 /etc/issue # 查看操作系统版本# cat /proc/cpuinfo # 查看C ...