POJ 2253 Frogger(最小生成树)
青蛙跳跃,题意大概是:青蛙从起点到终点进行一次或多次的跳跃,多次跳跃中肯定有最大的跳跃距离。求在所有的跳跃中,最小的最大跳跃距离SF-_-(不理解?看题目吧)。
可以用最小生成树完成。以起点为根,生成一棵最小生成树,直到树里包含了终点。
或者这么说吧,类似于Kruskal算法,我们每次选取不成环的最小边,直到这棵树选取了通往终点的最小边,那么最后选择的这条边必然是在树中最大的一条边,而且在其余的边中是最小的。你不会找到比这条边小的最大距离,因为比它小的最小距离都在树里了,而未选取该边前树中不包含终点,即比该边小的所有边无法到达终点。即改边满足的两个条件,最小,而且是起点到终点的最大距离(PS:挺绕的……)。
既然有思路了,可以直接写代码了。先是上面的Kruskal算法(16MS):
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
using namespace std; int root[];
int x[],y[]; int find(int x)
{
return root[x]?root[x]=find(root[x]):x;
} bool union_set(int a,int b)
{
a=find(a);
b=find(b);
if(a==b)
return false;
root[b]=a;
return true;
} struct Edge
{
int x,y,dis;
bool operator<(const Edge& cmp) const
{
return dis<cmp.dis;
}
} edge[]; int main()
{
// freopen("in.txt","r",stdin);
int n,cas=;
while(~scanf("%d",&n) && n)
{
memset(root,,sizeof(root));
for(int i=;i<=n;i++)
scanf("%d%d",x+i,y+i);
int index=;
for(int i=;i<=n;i++)
{
for(int j=i+;j<=n;j++)
{
edge[index].x=i;
edge[index].y=j;
edge[index++].dis=(x[i]-x[j])*(x[i]-x[j])+(y[i]-y[j])*(y[i]-y[j]);
}
}
sort(edge,edge+index); int maxE=;
for(int i=;i<index;i++)
{
if(union_set(edge[i].x,edge[i].y))
{
if(find()==find())
{
maxE=edge[i].dis;
break;
}
}
}
printf("Scenario #%d\n",cas++);
printf("Frog Distance = %.3f\n\n",sqrt((double)maxE));
}
}
使用并查集的Kruskal算法明显要好写一点。但是这题每两点之间必然有一条边,是一个稠密图,Prim算法更适合一些。下面是Prim算法的代码:
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <queue>
using namespace std; struct Node
{
int k,w;
bool operator<(const Node& cmp) const
{
return w>cmp.w;
}
} p,q; bool vis[];
int x[],y[];
int first[],vv[],ww[],nxt[]; int main()
{
// freopen("in.txt","r",stdin);
int n,cas=;
while(~scanf("%d",&n) && n)
{
priority_queue <Node> pq;
memset(vis,,sizeof(vis));
memset(first,,sizeof(first)); for(int i=;i<=n;i++)
scanf("%d%d",x+i,y+i); int e=;
for(int i=;i<=n;i++)
{
for(int j=i+;j<=n;j++)
{
nxt[e]=first[i],vv[e]=j;
ww[e+]=ww[e]=(x[i]-x[j])*(x[i]-x[j])+(y[i]-y[j])*(y[i]-y[j]);
first[i]=e++;
nxt[e]=first[j],vv[e]=i;
first[j]=e++;
}
} p.k=;
p.w=;
pq.push(p); int maxE=;
while(!pq.empty())
{
p=pq.top();
pq.pop();
maxE=max(maxE,p.w);
if(p.k==)
break;
if(vis[p.k])
continue;
vis[p.k]=true; for(int e=first[p.k];e;e=nxt[e]) if(!vis[vv[e]])
{
q.k=vv[e];
q.w=ww[e];
pq.push(q);
}
} printf("Scenario #%d\n",cas++);
printf("Frog Distance = %.3f\n\n",sqrt((double)maxE));
}
}
需要注意的是Kruskal算法最终的判定是起点和终点是否同一集合,如果是,最大距离就是最后一条边的距离。而prim算法的最大边需要实时更新,因为先选的边可能大于后来选择的边。搞笑的是Prim算法也是16MS,不知道是不是我写的效率有问题SF0_0。夜深人静的时候在去跑跑吧……
POJ 2253 Frogger(最小生成树)的更多相关文章
- 最短路(Floyd_Warshall) POJ 2253 Frogger
题目传送门 /* 最短路:Floyd算法模板题 */ #include <cstdio> #include <iostream> #include <algorithm& ...
- POJ 2253 Frogger ,poj3660Cow Contest(判断绝对顺序)(最短路,floyed)
POJ 2253 Frogger题目意思就是求所有路径中最大路径中的最小值. #include<iostream> #include<cstdio> #include<s ...
- POJ. 2253 Frogger (Dijkstra )
POJ. 2253 Frogger (Dijkstra ) 题意分析 首先给出n个点的坐标,其中第一个点的坐标为青蛙1的坐标,第二个点的坐标为青蛙2的坐标.给出的n个点,两两双向互通,求出由1到2可行 ...
- POJ 2253 Frogger(dijkstra 最短路
POJ 2253 Frogger Freddy Frog is sitting on a stone in the middle of a lake. Suddenly he notices Fion ...
- poj 2253 Frogger 最小瓶颈路(变形的最小生成树 prim算法解决(需要很好的理解prim))
传送门: http://poj.org/problem?id=2253 Frogger Time Limit: 1000MS Memory Limit: 65536K Total Submissi ...
- POJ 2253 Frogger
题目链接:http://poj.org/problem?id=2253 Frogger Time Limit: 1000MS Memory Limit: 65536K Total Submissi ...
- poj 2253 Frogger (dijkstra最短路)
题目链接:http://poj.org/problem?id=2253 Frogger Time Limit: 1000MS Memory Limit: 65536K Total Submissi ...
- POJ 2253 ——Frogger——————【最短路、Dijkstra、最长边最小化】
Frogger Time Limit:1000MS Memory Limit:65536KB 64bit IO Format:%I64d & %I64u Submit Stat ...
- POJ 2253 Frogger Floyd
原题链接:http://poj.org/problem?id=2253 Frogger Time Limit: 1000MS Memory Limit: 65536K Total Submissi ...
- poj 2253 Frogger (最长路中的最短路)
链接:poj 2253 题意:给出青蛙A,B和若干石头的坐标,现青蛙A想到青蛙B那,A可通过随意石头到达B, 问从A到B多条路径中的最长边中的最短距离 分析:这题是最短路的变形,曾经求的是路径总长的最 ...
随机推荐
- Linux启动提示“unexpected inconsistency;RUN fsck MANUALLY”
问题:在开机启动时,提示“unexpected inconsistency;RUN fsck MANUALLY”进不了系统 解决方法: fsck不仅可以对文件系统进行扫描,还能修正文件系统的一些问题, ...
- openwrt虚拟机的network unreachable
之前在hyper-v中装了openwrt的ATTITUDE ADJUSTMENT (12.09, r36088)这个最新版本 我之前的文章有提到怎么安装 link 但是发现用opkg update不能 ...
- Java知识总结--CoreJava
在网上看到的关于Java的知识总结,觉得很受用,分享给大家..... 如果有什么错误,也欢迎指正批评. 1 简述下java基本数据类型及所占位数,java基本数据类型:4类8种 整数类型:byte(1 ...
- PHP初学留神(一)
1.转义字符的使用 这个问题是在php下编写SQL语句的字符串时遇到的,因为在where后面的条件判断经常要用到双引号("")来表示字符.而诸如下面这样的语句就会报错. $quer ...
- numpy+scipy+matlotlib+scikit-learn的安装及问题解决
NumPy(Numeric Python)系统是Python的一种开源的数值计算扩展,一个用python实现的科学计算包.它提供了许多高级的数值编程工具,如:矩阵数据类型.矢量处理,以及精密的运算库. ...
- 用PLSQL Developer粘贴数据的时候报oracle variant conversion error for variable v0
参考文章:http://bugcool.blog.51cto.com/2080571/664434 两个数据库表对着copy粘贴的时候,报这个错.只是我这边不是顺序不对,不知道为什么其中的一行换行了. ...
- JAVA技术体系发展路线
JAVA技术体系 1.1 Java程序员 ·高级特性 反射.泛型.注释符.自动装箱和拆箱.枚举类.可变参数.可变返回类型.增强循环.静态导入 ·核心编程 IO.多线程.实体类.集合类.正则表达式.XM ...
- 2016030206 - mysql常用命令
参考地址如下: http://www.cnblogs.com/linjiqin/archive/2013/03/01/2939384.html http://www.cnblogs.com/zhang ...
- 破坏之王——ddos攻击与防范 读书笔记
好久没写博客了,最近把绿盟的<破坏之王——ddos攻击与防范>又翻了一下,整理了关于DDOS分类和原理的xmind图~~ 百度云盘:http://pan.baidu.com/s/1i3ms ...
- cocos2dx伸缩式列表效果
效果: 代码: ElasticListView.h #pragma once //std #include <string> #include <map> //cocos #i ...