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多条路径中的最长边中的最短距离 分析:这题是最短路的变形,曾经求的是路径总长的最 ...
随机推荐
- C++动态二维数组的创建
两种方式. 一,二级指针,创建2行3列的动态二维数组. 这里,p指向的是2个地址,这两个地址各指向长度为3的一维整型数组. 在内存中,每行元素内部顺序排列.两行元素的首地址不同,p[1]与p[2]存放 ...
- 使用qt制作简单的加法,乘法运算。
1.首先构架qt应用项目 2.然后打开使用 Qt desinger打开 Fomr File 里的UI文件进行编辑 3.由于此程序只需点击加号,减号这两个按钮,所以设置了两个信号槽 4.然后是连接信号槽 ...
- TweenMax动画库学习(二)
目录 TweenMax动画库学习(一) TweenMax动画库学习(二) TweenMax动画库学习(三) Tw ...
- 4个好用的JS联动选择插件
jQuery City Select 一个简单的jQuery省市联动插件,可以自定义JSON字典实现其他内容的联动选择菜单. PCAS省.市.地区联动选择JS封装类 PCAS可能是国内使用人数最多的J ...
- WPF的ScrollViewer鼠标的滚动
在C# 中,两个ScrollViewer嵌套在一起或者ScrollViewer里面嵌套一个ListBox.Listview(控件本身有scrollviewer)的时候,我们本想要的效果是鼠标滚动整个S ...
- pymssql 安装测试
平台 : windows 7 32位 数据库 : SQLSERVER 2008 python 2.7 & pymssql模块 数据库和python 等模块安装说明省略 以下贴出测试代码: 单 ...
- 关于ASE日志空间示数不正常的解决办法
最近某系统的ASE数据库出现了异常,经过各种努力,终于把数据库正常又起起来了.但是经过检查,发现在查看剩余日志空间的时候(sp_helpsegment 'logsegment'),发现显示出来 ...
- 6.MVC框架开发(文件上传)
1.需要设置表单的enctype="multipart/form-data"属性 2.在控制器中获取表单文件中数据 [HttpPost] public ActionResult A ...
- VisualStudio自定义代码段_方法一
在VisualStudio里,使用代码段会提高我们的编写速度.其实,就是给一段代码加个快捷方式,使用时,快捷方式按键+2次Tab键. 举个例子: 比如输入Console.WriteLine (); 传 ...
- NUTCH Exception in thread "Thread-12751" java.lang.OutOfMemoryError: PermGen space
转载自 :http://greemranqq.iteye.com/blog/1705867转载自:http://www.cnblogs.com/xwdreamer/archive/2011/11/21 ...