POJ 2253 连通图的最小边问题(转载)
2010-04-25 20:29
295 查看
/*Dij的变形,这道题目的意思大致是,给你起点和终点,还有一些可用来中间过度的点,首先保证你能够跳跃到终点,
同时还要保证你的跳跃跨度最小,也就是从起点到终点路径上的最大的那条边要尽量小,这个有点绕,所以我把这道题
目改一下
等价题:假设你在玩一个闯关游戏,目的是到达终点闯关,走哪条路无关紧要,你把那些点之间的路径看成是怪物,路
径长度看成是怪物的能量值,如果你想击败怪物顺利闯关的话,你的能量值必须高于怪物的能量值,当然获得能量值是
需要付出代价的,现在你想用最少的代价通关,求这个最小的能量值是多少?不难想到,此题可以用Dij来解,只需要
把sum改成max即可。不得不提的是,这里不是求最短路径,而是求连通图的最小边的问题,它们都可以用Dij,个人感觉
它们似乎是平行的关系,只不过是Dij大环境下的2个变种罢了。在最短路径问题中,dis[i]数组中存储的是,i点到原点
的最小距离,而在连通图最小边问题中,dis[i]数组中存储的是i点到周围任何一个点的最小距离(当然这个距离是通过不
断的松弛,最后才得到的*/
#include <stdio.h>
#include <math.h>
#include <string.h>
#include <limits> //引入limits头文件
using namespace std;
typedef struct stone
{
int xi;
int yi;
}stone;
#define arraysize 201
stone stones[arraysize];
double dis[arraysize][arraysize];
bool final[arraysize];
double d[arraysize];
int n;
int num;
double max = numeric_limits<double>::max(); //double 的最大值
void Dij()
{
memset(final,0,sizeof(final));
memset(d,0,sizeof(d));
double fgdistance = 0;
for(int i3=1;i3<n+1;++i3)
{
d[i3] = dis[1][i3];
}
final[1] = true;
d[1] = 0;
for(int i=1;i<n;++i)
{
double min = max;
int v = 1;
for(int i1=2;i1<n+1;i1++)
{
if(!final[i1] && min>d[i1])
{
min = d[i1];
v = i1;
}
}
final[v] = true;
//此处是关键
if(min>fgdistance)
{
fgdistance = min;
}
if(v==2)
break;
for(int i2=2;i2<n+1;i2++)
{
if(!final[i2])
{
if(dis[v][i2]<d[i2])
{
d[i2] = dis[v][i2];
}
}
}
}
printf("Scenario #%d\n",num);
printf("Frog Distance = %.3f\n\n",fgdistance);
}
int main()
{
stone start,end;
num = 0;
//freopen("1.txt","r",stdin);
while(scanf("%d",&n) && n!=0)
{
int xi,yi;
for(int i=1;i<n+1;++i)
{
scanf("%d%d",&xi,&yi);
stones[i].xi = xi;
stones[i].yi = yi;
}
for(int i1=1;i1<n+1;++i1)
{
for(int i2=1;i2<n+1;++i2)
{
int xm = stones[i1].xi - stones[i2].xi;
int ym = stones[i1].yi - stones[i2].yi;
dis[i1][i2] = sqrt(double(xm*xm+ym*ym)); //此处别忘了加double,否则会出现编译时错误
dis[i2][i1] = dis[i1][i2];
}
}
num++;
Dij();
}
return 0;
}
同时还要保证你的跳跃跨度最小,也就是从起点到终点路径上的最大的那条边要尽量小,这个有点绕,所以我把这道题
目改一下
等价题:假设你在玩一个闯关游戏,目的是到达终点闯关,走哪条路无关紧要,你把那些点之间的路径看成是怪物,路
径长度看成是怪物的能量值,如果你想击败怪物顺利闯关的话,你的能量值必须高于怪物的能量值,当然获得能量值是
需要付出代价的,现在你想用最少的代价通关,求这个最小的能量值是多少?不难想到,此题可以用Dij来解,只需要
把sum改成max即可。不得不提的是,这里不是求最短路径,而是求连通图的最小边的问题,它们都可以用Dij,个人感觉
它们似乎是平行的关系,只不过是Dij大环境下的2个变种罢了。在最短路径问题中,dis[i]数组中存储的是,i点到原点
的最小距离,而在连通图最小边问题中,dis[i]数组中存储的是i点到周围任何一个点的最小距离(当然这个距离是通过不
断的松弛,最后才得到的*/
#include <stdio.h>
#include <math.h>
#include <string.h>
#include <limits> //引入limits头文件
using namespace std;
typedef struct stone
{
int xi;
int yi;
}stone;
#define arraysize 201
stone stones[arraysize];
double dis[arraysize][arraysize];
bool final[arraysize];
double d[arraysize];
int n;
int num;
double max = numeric_limits<double>::max(); //double 的最大值
void Dij()
{
memset(final,0,sizeof(final));
memset(d,0,sizeof(d));
double fgdistance = 0;
for(int i3=1;i3<n+1;++i3)
{
d[i3] = dis[1][i3];
}
final[1] = true;
d[1] = 0;
for(int i=1;i<n;++i)
{
double min = max;
int v = 1;
for(int i1=2;i1<n+1;i1++)
{
if(!final[i1] && min>d[i1])
{
min = d[i1];
v = i1;
}
}
final[v] = true;
//此处是关键
if(min>fgdistance)
{
fgdistance = min;
}
if(v==2)
break;
for(int i2=2;i2<n+1;i2++)
{
if(!final[i2])
{
if(dis[v][i2]<d[i2])
{
d[i2] = dis[v][i2];
}
}
}
}
printf("Scenario #%d\n",num);
printf("Frog Distance = %.3f\n\n",fgdistance);
}
int main()
{
stone start,end;
num = 0;
//freopen("1.txt","r",stdin);
while(scanf("%d",&n) && n!=0)
{
int xi,yi;
for(int i=1;i<n+1;++i)
{
scanf("%d%d",&xi,&yi);
stones[i].xi = xi;
stones[i].yi = yi;
}
for(int i1=1;i1<n+1;++i1)
{
for(int i2=1;i2<n+1;++i2)
{
int xm = stones[i1].xi - stones[i2].xi;
int ym = stones[i1].yi - stones[i2].yi;
dis[i1][i2] = sqrt(double(xm*xm+ym*ym)); //此处别忘了加double,否则会出现编译时错误
dis[i2][i1] = dis[i1][i2];
}
}
num++;
Dij();
}
return 0;
}
相关文章推荐
- Poj 2253 + 1797 + 1502 最短路的最小最大值问题
- poj 2594(最小路径覆盖问题)
- poj 2226 还是最小点覆盖的匹配问题
- poj 2253 最小生成树 kruskal
- POJ 3167 字典序最小问题
- POJ 3101 Astronomy 轨道相遇问题,求n个分数的最小公倍数
- 相邻区域染色最小染色数问题 POJ 1129
- poj 1251 最小生成树问题
- poj 3681 Finding the Rectangle 尺取法解最小矩形覆盖问题
- RMQ 问题 POJ 3264 求解任意指定区间内的最小值和最大值
- 【转载】poj 1276 Cash Machine 【凑钱数的问题】【枚举思路 或者 多重背包解决】
- POJ 2253 Frogger (最小生成树 or 最短路变形)
- poj 3041 二分图最大匹配(最小点覆盖问题)
- POJ 2406 (字符串的匹配) 最小循环节问题
- poj 2253(最小生成树)
- 点连通度 边连通度 最大流最小割 最小割点集 最小割边集 & POJ 1966 Cable TV Network
- POJ 2253 Frogger (dijkstra 最大边最小)
- POJ-1797Heavy Transportation (最小生成树问题)
- (Warshall13.1.1)POJ 2253(计算任意一对顶点之间的连通性||求最大路的最小值——图的传递闭包)
- POJ 3469->Dual Core CPU(最大流最小割问题)