hdu 4463 Outlets(最小生成树)
题意: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(最小生成树)的更多相关文章
- HDU—4463 Outlets 最小生成树
In China, foreign brand commodities are often much more expensive than abroad. The main reason is th ...
- hdu 4463 Outlets(最小生成树)
Outlets Time Limit : 2000/1000ms (Java/Other) Memory Limit : 32768/32768K (Java/Other) Total Submi ...
- 【HDU 4463 Outlets】最小生成树(prim,kruscal都可)
以(x,y)坐标的形式给出n个点,修建若干条路使得所有点连通(其中有两个给出的特殊点必须相邻),求所有路的总长度的最小值. 因对所修的路的形状没有限制,所以可看成带权无向完全图,边权值为两点间距离.因 ...
- HDU 4463 Outlets(最小生成树给坐标)
Problem Description In China, foreign brand commodities are often much more expensive than abroad. T ...
- HDU 4463 Outlets (最小生成树)
题意:给定n个点坐标,并且两个点已经连接,但是其他的都没有连接,但是要找出一条最短的路走过所有的点,并且路线最短. 析:这个想仔细想想,就是应该是最小生成树,把所有两点都可以连接的当作边,然后按最小生 ...
- HDU 4463 Outlets 【最小生成树】
<题目链接> 题目大意: 给你一些点的坐标,要求你将这些点全部连起来,但是必须要包含某一条特殊的边,问你连起这些点的总最短距离是多少. 解题分析: 因为一定要包含那条边,我们就记录下那条边 ...
- hdu 4463 Outlets
#include<bits/stdc++.h> using namespace std; double x[100+5],y[100+5]; double e[100+5][100+5]; ...
- hdu Constructing Roads (最小生成树)
题目:http://acm.hdu.edu.cn/showproblem.php?pid=1102 /************************************************* ...
- hdu 4463 第37届ACM/ICPC杭州赛区K题 最小生成树
题意:给坐标系上的一些点,其中有两个点已经连了一条边,求最小生成树的值 将已连接的两点权值置为0,这样一定能加入最小生成树里 最后的结果加上这两点的距离即为所求 #include<cstdio& ...
随机推荐
- hdu 5288 ZCC loves straight flush
传送门 ZCC loves straight flush Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 131072/65536 K ...
- msp430项目编程44
msp430综合项目---门禁控制系统44 1.电路工作原理 2.代码(显示部分) 3.代码(功能实现) 4.项目总结
- Container With Most Water 双指针法
Given n non-negative integers a1, a2, ..., an, where each represents a point at coordinate (i, ai). ...
- Oracle 12c安装报错Installation failed to access the temporary location(无法访问临时位置)
报错如图 1.先检查当前windows账户用户名是否为全英文,没有就新建一个,大多数用户败在这一步,而官方也没有解释 如何新建:开始-->控制面板-->用户账户和家庭安全-->用户账 ...
- cssnext下一代的css
前端技术更新迭代的速度令人咂舌,互联网+的风头刚起那几年,前端技术大多还停留在jquery阶段,按需加载还停留在seajs和requirejs的阶段,css3和H5也不过才崭露头角,但经过几年的飞速发 ...
- 真的了解CDN服务吗?
Im CDN,WOW,COOL CDN知识详解 全称:Content Delivery Network或Content Ddistribute Network,即内容分发网络,CDN是构建在网络之上的 ...
- codevs——1958 刺激
1958 刺激 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 黄金 Gold 题解 题目描述 Description saffah的一个朋友S酷爱滑雪,并且追求刺 ...
- RED HAT 7 性能监控工具
https://access.redhat.com/documentation/zh-CN/Red_Hat_Enterprise_Linux/7/html/Performance_Tuning_Gui ...
- Mac Ubuntu ----端口被占用
Mac下使用lsof(list open files)来查看端口占用情况,lsof 是一个列出当前系统打开文件的工具. 使用 lsof 会列举所有占用的端口列表: 1 $ lsof 使用less可以用 ...
- go使用时间作为种子生成随机数
原文:http://blog.csdn.net/qq_15437667/article/details/50851159 --------------------------------------- ...