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算法)的更多相关文章

  1. POJ-1789 Truck History---最小生成树Prim算法

    题目链接: https://vjudge.net/problem/POJ-1789 题目大意: 用一个7位的string代表一个编号,两个编号之间的distance代表这两个编号之间不同字母的个数.一 ...

  2. 10-最小生成树-Prim算法

    #include <iostream> #include <cstring> #include <cstdio> using namespace std; #def ...

  3. UVA 10462 Is There A Second Way Left?(次小生成树&Prim&Kruskal)题解

    思路: Prim: 这道题目中有重边 Prim可以先加一个sec数组来保存重边的次小边,这样不会影响到最小生成树,在算次小生成树时要同时判断次小边(不需判断是否在MST中) Kruskal: Krus ...

  4. hdu 4081 Qin Shi Huang's National Road System(次小生成树prim)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4081 题意:有n个城市,秦始皇要修用n-1条路把它们连起来,要求从任一点出发,都可以到达其它的任意点. ...

  5. UVA10462Is There A Second Way Left? —— 次小生成树 kruskal算法

    题目链接:https://vjudge.net/problem/UVA-10462 Nasa, being the most talented programmer of his time, can’ ...

  6. 次小生成树(Prim + Kruaskal)

    问题引入: 我们先来回想一下生成树是如何定义的,生成树就是用n - 1条边将图中的所有n个顶点都连通为一个连通分量,这样的边连成子树称为生成树. 最小生成树很明显就是生成树中权值最小的生成树,那么我们 ...

  7. The Unique MST POJ - 1679 次小生成树prim

    求次小生成树思路: 先把最小生成树求出来  用一个Max[i][j] 数组把  i点到j 点的道路中 权值最大的那个记录下来 used数组记录该条边有没有被最小生成树使用过   把没有使用过的一条边加 ...

  8. poj1789--最小生成树(prim)

    水题... 题目大意: 用一个7位的字符串代表一个编号,两个编号之间的distance代表这两个编号之间不同字母的个数.一个编号只能由另一个编号“衍生”出来,代价是这两个编号之间相应的distance ...

  9. POJ 1679 The Unique MST (次小生成树kruskal算法)

    The Unique MST 时间限制: 10 Sec  内存限制: 128 MB提交: 25  解决: 10[提交][状态][讨论版] 题目描述 Given a connected undirect ...

随机推荐

  1. 西南民族大学第十二届程序设计竞赛(同步赛) A.逃出机房 (bfs)

    题意:有来两个人A和B,A追B,A和B每次向上下左右移动一个单位,一共有两扇门,问A是否可以追上B(在门口追上也算合法). 题解:当时看题意说在门口也算?就觉得是判断两个人到门口的时间,对他们两个人分 ...

  2. bnuoj24252 Divide

    Alice and Bob has found a island of treasure in byteland! They find N kinds of treasures on the isla ...

  3. CodeForces - 612D 思维

    题意: 给你n个线段和一个整数k,你需要找出来所有能被任意k条线段同时覆盖的区间个数的最小值,并按从左到右的顺序输出每个区间. 题解: 对于题目输入的n个线段的左端点L,右端点R,把它们分开放在结构体 ...

  4. hdu4533 威威猫系列故事——晒被子

    Problem Description 因为马拉松初赛中吃鸡腿的题目让不少人抱憾而归,威威猫一直觉得愧对大家,这几天他悄悄搬到直角坐标系里去住了. 生活还要继续,太阳也照常升起,今天,威威猫在第一象限 ...

  5. CF1462-F. The Treasure of The Segments

    题意: 给出n个线段组成的集合,第i个线段用 \(\{l_i, r_i\}\) 表示线段从坐标轴的点\(l_i\)横跨到点\(r_i\).现在你可以删除其中的一些线段,使得剩下的线段组成的集合中至少存 ...

  6. LINUX - Libevent

    参考: https://dulishu.top/libevent-event-loop/

  7. 实现 MyBatis 流式查询的方法

    基本概念流式查询指的是查询成功后不是返回一个集合而是返回一个迭代器,应用每次从迭代器取一条查询结果.流式查询的好处是能够降低内存使用.如果没有流式查询,我们想要从数据库取 1000 万条记录而又没有足 ...

  8. Python errors All In One

    Python errors All In One SyntaxError: invalid character in identifier \u200b, ZERO WIDTH SPACE https ...

  9. MBP 屏幕分辨率 All In One

    MBP 屏幕分辨率 All In One screen size bug https://stackoverflow.com/questions/65462643/how-to-get-the-rea ...

  10. js regular expression & email checker

    js regular expression & email checker const isValidEmail = (email = ``) => /^([\w+\.])+@(\w+) ...