题意:n个点修路,要求总长度最小,但是有两个点p、q必须相连

思路:完全图,prim算法的效率取决于节点数,适用于稠密图。用prim求解。

p、q间距离设为0即可,最后输出时加上p、q间的距离

prim算法:

#include<iostream>
#include<stdio.h>
#include<string.h>
#include<math.h>
using namespace std; #define INF 15000//计算得最长值
#define MAXN 128
bool vis[MAXN];
double lowc[MAXN]; struct Point{
double x,y;
}p[MAXN]; double dis(Point a,Point b){
return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));
} double prim(double cost[][MAXN],int n){//标号从0开始
double ans=,minc;
int i,j,p;
memset(vis,false,sizeof(vis));
vis[]=true;
for(i=;i<n;++i)lowc[i]=cost[][i];
for(i=;i<n;++i){
minc=INF;
p=-;
for(j=;j<n;++j)
if(!vis[j]&&lowc[j]<minc){
minc=lowc[j];
p=j;
}
if(minc==INF)return -;//原图不连通
ans+=minc;
vis[p]=true;
for(j=;j<n;++j)
if(!vis[j]&&cost[p][j]<lowc[j])
lowc[j]=cost[p][j];
}
return ans;
} int main(){
int n,m,a,b,i,j;
double cost[MAXN][MAXN],w;
while(~scanf("%d",&n)&&n){
//m=n*(n-1)/2;//m边条数
scanf("%d%d",&a,&b);
--a;--b;
for(i=;i<n;++i)
scanf("%lf%lf",&p[i].x,&p[i].y); for(i=;i<n;++i)
for(j=i+;j<n;++j){
w=dis(p[i],p[j]);
if((i==a&&j==b)||(j==a&&i==b))w=;
cost[i][j]=cost[j][i]=w;
}
printf("%.2f\n",prim(cost,n)+dis(p[a],p[b]));
}
return ;
}

kruskal算法的效率取决于边数,适用于稀疏图。

边数为50*50,也不是很多,也可用kruskal算法:

#include<iostream>
#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<math.h>
using namespace std; #define MAXN 110//最大点数
#define MAXM 10000//最大边数
int F[MAXN];//并查集使用 struct Point{
double x,y;
}p[MAXN]; struct Edge{
int u,v;
double w;
}edge[MAXM];//存储边的信息,包括起点/终点/权值
int tol;//边数,加边前赋值为0 double dis(Point a,Point b){
return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));
} void addedge(int u,int v,double w){
edge[tol].u=u;
edge[tol].v=v;
edge[tol++].w=w;
} //排序函数,将边按照权值从小到大排序
bool cmp(Edge a,Edge b){
return a.w<b.w;
} int find(int x){
if(F[x]==-)return x;
return F[x]=find(F[x]);
} //传入点数,返回最小生成树的权值,如果不连通返回-1
double kruskal(int n){
memset(F,-,sizeof(F));
sort(edge,edge+tol,cmp);
int cnt=;//计算加入的边数
int i,u,v,t1,t2;
double w,ans=;
for(i=;i<tol;++i){
u=edge[i].u;
v=edge[i].v;
w=edge[i].w;
t1=find(u);
t2=find(v);
if(t1!=t2){
ans+=w;
F[t1]=t2;
++cnt;
}
if(cnt==n-)break;
}
if(cnt<n-)return -;//不连通
return ans;
} int main(){
int n,a,b,i,j;
double w;
while(~scanf("%d",&n)&&n){
scanf("%d%d",&a,&b);
for(i=;i<=n;++i)
scanf("%lf%lf",&p[i].x,&p[i].y); tol=;
for(i=;i<=n;++i)
for(j=i+;j<=n;++j){
w=dis(p[i],p[j]);
if((i==a&&j==b)||(j==a&&i==b))w=;
addedge(i,j,w);
}
printf("%.2f\n",kruskal(n)+dis(p[a],p[b]));
}
return ;
}

hdu 4463 Outlets(最小生成树)的更多相关文章

  1. HDU—4463 Outlets 最小生成树

    In China, foreign brand commodities are often much more expensive than abroad. The main reason is th ...

  2. hdu 4463 Outlets(最小生成树)

    Outlets Time Limit : 2000/1000ms (Java/Other)   Memory Limit : 32768/32768K (Java/Other) Total Submi ...

  3. 【HDU 4463 Outlets】最小生成树(prim,kruscal都可)

    以(x,y)坐标的形式给出n个点,修建若干条路使得所有点连通(其中有两个给出的特殊点必须相邻),求所有路的总长度的最小值. 因对所修的路的形状没有限制,所以可看成带权无向完全图,边权值为两点间距离.因 ...

  4. HDU 4463 Outlets(最小生成树给坐标)

    Problem Description In China, foreign brand commodities are often much more expensive than abroad. T ...

  5. HDU 4463 Outlets (最小生成树)

    题意:给定n个点坐标,并且两个点已经连接,但是其他的都没有连接,但是要找出一条最短的路走过所有的点,并且路线最短. 析:这个想仔细想想,就是应该是最小生成树,把所有两点都可以连接的当作边,然后按最小生 ...

  6. HDU 4463 Outlets 【最小生成树】

    <题目链接> 题目大意: 给你一些点的坐标,要求你将这些点全部连起来,但是必须要包含某一条特殊的边,问你连起这些点的总最短距离是多少. 解题分析: 因为一定要包含那条边,我们就记录下那条边 ...

  7. hdu 4463 Outlets

    #include<bits/stdc++.h> using namespace std; double x[100+5],y[100+5]; double e[100+5][100+5]; ...

  8. hdu Constructing Roads (最小生成树)

    题目:http://acm.hdu.edu.cn/showproblem.php?pid=1102 /************************************************* ...

  9. hdu 4463 第37届ACM/ICPC杭州赛区K题 最小生成树

    题意:给坐标系上的一些点,其中有两个点已经连了一条边,求最小生成树的值 将已连接的两点权值置为0,这样一定能加入最小生成树里 最后的结果加上这两点的距离即为所求 #include<cstdio& ...

随机推荐

  1. 关于EOF,转自新浪微博

    本文转自http://blog.sina.com.cn/s/blog_7714171f0101798y.html EOF 是 End Of File 的缩写. 在C语言中,它是在标准库中定义的一个宏. ...

  2. 学习技术的三部曲:WHAT、HOW、WHY

    ★第一步:WHAT 所谓的“WHAT”也就是“What is it?”——这是最简单的层次.在这个层次,你要搞清楚某个东东是[什么]样子的?有[什么]用处?有[什么]特性?有[什么]语法?...... ...

  3. Android-一张图理解MVP的用法

    M和V通过P交互,M做了两件事,开启子线程做耗时操作,然后使用原生的Hander方式切回主线程回调结果给P. M做的两件事也可以使用比较流行的rxjava实现: 备注:图片不清晰可以看这里

  4. idea tomcat 配置

    昨天我们讲了如何新建多模块项目:idea创建maven多模块项目 本节课,我们讲如何配置tomcat,使昨天配置的web项目,JRapid.Admin可以运行起来.具体步骤如下 第一步 第二步 第三步 ...

  5. Linux驱动基础开发

    Linux 内核配置机制(make menuconfig.Kconfig.makefile)讲解 前面我们介绍模块编程的时候介绍了驱动进入内核有两种方式:模块和直接编译进内核,并介绍了模块的一种编译方 ...

  6. 前端编程提高之旅(十)----表单验证插件与cookie插件

        实际项目开发中与用户交互的常见手法就是採用表单的形式.取得用户注冊.登录等信息.而当用户注冊或登录后又须要记住用户的登录状态.这就涉及到经常使用的两个操作:表单验证与cookie增删查找.   ...

  7. 使用Python控制1602液晶屏实时显示时间(附PyCharm远程调试)

    前言 原创文章,转载引用务必注明链接.水平有限,如有疏漏,欢迎指正. 本文介绍一下UP板的GPIO资源使用,以及一个使用Python演示一个简单的demo. 本文使用Markdown写成,为获得更好的 ...

  8. 2014牡丹江 现场赛 F zoj 3824 Fiber-optic Network

    首先赞一下题目, 好题 题意: Marjar University has decided to upgrade the infrastructure of school intranet by us ...

  9. eclipse中progress一直在刷新问题处理

  10. stream_context_create()模拟POST/GET

    有时候,我们需要在服务器端模拟 POST/GET 等请求,也就是在 PHP 程序中去实现模拟,该怎么做到呢?或者说,在 PHP 程序里,给你一个数组,如何将这个数组 POST/GET 到另外一个地址呢 ...