HDOJ-4081(次小生成树+Prim算法)
Qin Shi Huang's National Road System
HDOJ-4081
- 本题考查的是次小生成树的问题,这里的解决方法就是先使用Prim算法求解最小生成树。
- 在求解最小生成树的时候通过一个数组记录每一对顶点之间的路径上长度最长的一条边。这个由一个cost数组记录。
- 最后,再依次遍历每一对顶点,如果这对顶点不在最小生成树里面,则直接去掉这条边改成魔法边。否则就将这对顶点之间的那条路径上面最长的一条边去掉,用i,j这对顶点代替。
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<string>
#include<vector>
#include<cmath>
using namespace std;
const int maxn=1004;
const int maxm=1000006;
const int INF=0x3f3f3f3f;
int n;//nodes
int m;//edges
struct node{
int x;
int y;
int p;//人口
};
node cities[maxn];
struct edge{
int from;
int to;
double w;//distance
};
edge edges[maxm];
double map[maxn][maxn];
double mincost[maxn];
bool used[maxn];
int father[maxn];
double cost[maxn][maxn];//表示i,j路径上最长的一条边的长度
double cal(int i,int j){
double x=(double)((cities[i].x-cities[j].x)*(cities[i].x-cities[j].x));
double y=(double)((cities[i].y-cities[j].y)*(cities[i].y-cities[j].y));
return sqrt(x+y);
}
double prim(){
memset(cost,0,sizeof(cost));
for(int i=0;i<n;i++){
mincost[i]=INF;
used[i]=0;
father[i]=i;
}
mincost[0]=0;
double ans=0;//总和长度
while(true){
int v=-1;
for(int u=0;u<n;u++){
if(!used[u]&&(v==-1||mincost[u]<mincost[v])){
v=u;
}
}
if(v==-1)
break;
used[v]=1;
ans+=mincost[v];
for(int j=0;j<n;j++){
if(j==v)
continue;
if(used[j])
cost[j][v]=cost[v][j]=max(mincost[v],cost[father[v]][j]);
}
for(int u=0;u<n;u++){
if(!used[u]&&mincost[u]>map[v][u]){
mincost[u]=map[v][u];
father[u]=v;
}
}
}
return ans;
}
int main(){
int t;
cin>>t;
while(t--){
cin>>n;
int x,y,p;
for(int i=0;i<n;i++){
cin>>x>>y>>p;
cities[i].x=x,cities[i].y=y,cities[i].p=p;
}
for(int i=0;i<n;i++){
for(int j=0;j<i;j++){
double dis=cal(i,j);
map[i][j]=dis;
map[j][i]=dis;
edges[m].from=i;
edges[m].to=j;
edges[m++].w=dis;
}
map[i][i]=0;
}
double distance=prim();
double ans=0;
for(int i=0;i<n;i++){
for(int j=0;j<n;j++){
if(i==j)
continue;
if(i!=father[j]&&j!=father[i]){//i,j这条边不在最小生成树里面
ans=max(ans,(cities[i].p+cities[j].p)/(distance-cost[i][j]));
}else{//i,j这条边在最小生成树里面
ans=max(ans,(cities[i].p+cities[j].p)/(distance-map[i][j]));
}
}
}
printf("%.2f\n",ans);//注意这里不需要加0.005,自动舍入为四舍五入
}
//system("pause");
return 0;
}
HDOJ-4081(次小生成树+Prim算法)的更多相关文章
- POJ-1789 Truck History---最小生成树Prim算法
题目链接: https://vjudge.net/problem/POJ-1789 题目大意: 用一个7位的string代表一个编号,两个编号之间的distance代表这两个编号之间不同字母的个数.一 ...
- 10-最小生成树-Prim算法
#include <iostream> #include <cstring> #include <cstdio> using namespace std; #def ...
- UVA 10462 Is There A Second Way Left?(次小生成树&Prim&Kruskal)题解
思路: Prim: 这道题目中有重边 Prim可以先加一个sec数组来保存重边的次小边,这样不会影响到最小生成树,在算次小生成树时要同时判断次小边(不需判断是否在MST中) Kruskal: Krus ...
- hdu 4081 Qin Shi Huang's National Road System(次小生成树prim)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4081 题意:有n个城市,秦始皇要修用n-1条路把它们连起来,要求从任一点出发,都可以到达其它的任意点. ...
- UVA10462Is There A Second Way Left? —— 次小生成树 kruskal算法
题目链接:https://vjudge.net/problem/UVA-10462 Nasa, being the most talented programmer of his time, can’ ...
- 次小生成树(Prim + Kruaskal)
问题引入: 我们先来回想一下生成树是如何定义的,生成树就是用n - 1条边将图中的所有n个顶点都连通为一个连通分量,这样的边连成子树称为生成树. 最小生成树很明显就是生成树中权值最小的生成树,那么我们 ...
- The Unique MST POJ - 1679 次小生成树prim
求次小生成树思路: 先把最小生成树求出来 用一个Max[i][j] 数组把 i点到j 点的道路中 权值最大的那个记录下来 used数组记录该条边有没有被最小生成树使用过 把没有使用过的一条边加 ...
- poj1789--最小生成树(prim)
水题... 题目大意: 用一个7位的字符串代表一个编号,两个编号之间的distance代表这两个编号之间不同字母的个数.一个编号只能由另一个编号“衍生”出来,代价是这两个编号之间相应的distance ...
- POJ 1679 The Unique MST (次小生成树kruskal算法)
The Unique MST 时间限制: 10 Sec 内存限制: 128 MB提交: 25 解决: 10[提交][状态][讨论版] 题目描述 Given a connected undirect ...
随机推荐
- 南阳ccpc C题 The Battle of Chibi && hdu5542 The Battle of Chibi (树状数组优化+dp)
题意: 给你一个长度为n的数组,你需要从中找一个长度为m的严格上升子序列 问你最多能找到多少个 题解: 我们先对原序列从小到大排序,排序之后的序列就是一个上升序列 这里如果两个数相等的话,那么因为题目 ...
- Broken robot CodeForces - 24D (三对角矩阵简化高斯消元+概率dp)
题意: 有一个N行M列的矩阵,机器人最初位于第i行和第j列.然后,机器人可以在每一步都转到另一个单元.目的是转到最底部(第N个)行.机器人可以停留在当前单元格处,向左移动,向右移动或移动到当前位置下方 ...
- Codeforces Round #479 (Div. 3) E. Cyclic Components (思维,DFS)
题意:给你\(n\)个顶点和\(m\)条边,问它们有多少个单环(无杂环),例如图中第二个就是一个杂环. 题解:不难发现,如果某几个点能够构成单环,那么每个点一定只能连两条边.所以我们先构建邻接表,然后 ...
- python代理池的构建5——对mongodb数据库里面代理ip检查
上一篇博客地址:python代理池的构建4--mongdb数据库的增删改查 一.对数据库里面代理ip检查(proxy_test.py) #-*-coding:utf-8-*- ''' 目的:检查代理I ...
- 分块 && 例题 I Hate It HDU - 1754
分块算法: 分块就是对暴力方法的一种优化: _ 假设我们总共的序列长度为n,然后我们把它切成√n 块,然后把每一块里的东西当成一个整体来看,完整块:被 ...
- WSL ubuntu重置密码
1. 在powershell中切换到root: 2. 进入ubuntu: 3. 修改制定用户的密码: 4. 切换回默认的用户:
- C#之Dispose
前言 谈到Dispose,首先需要理解C#的资源 资源类型 托管资源:由CLR创建和释放 非托管资源:资源的创建和释放不由CLR管理.比如IO.网络连接.数据库连接等等.需要开发人员手动释放. 如何释 ...
- keras fit_generator 并行
虽然已经走在 torch boy 的路上了, 还是把碰到的这个坑给记录一下 数据量较小时,我们可直接把整个数据集 load 到内存里,用 model.fit() 来拟合模型. 当数据集过大比如几十个 ...
- java-GUI编程学习总结
狂神说java-GUI编程学习总结 1.简介 2.AWT 2.1.实现如图1-2 (1)面向过程写法 (2)内部类写法 (3)完全改造成面向对象 3.Swing 3.1.鼠标花点 3.2.弹窗 3.3 ...
- 记一次 lampiao渗透(Drupal+脏牛提权)
vulnhub|渗透测试lampiao 题记 最近在打靶机,发现了一个挺有意思的靶机,这里想跟大家分享一下. 环境准备 vulnhub最近出的一台靶机 靶机(https://www.vulnhub.c ...