传送门:poj2253
题意就是求一号点到二号点之间各条路径中的最长边的最小值。
这题好气啊。。网上那么多种方法,我竟然一种都没想出来。。也只能说自己太浮躁了。
先是自己写的Floyd:
#include
#include
#include
#include
#define inf 0x3f3f3f3f
using namespace std;
int m;
struct node{
double r,c;
}q[205];
double mp[205][205];
int main()
{
int cnt=0;
while(~scanf("%d",&m)&&m)
{
cnt++;
for(int i=1;i<=m;i++)
scanf("%lf%lf",&q[i].r,&q[i].c);
for(int i=1;i<=m;i++)
for(int j=1;j<=m;j++)
{
mp[i][j]=(sqrt((q[i].r-q[j].r)*(q[i].r-q[j].r)+(q[i].c-q[j].c)*(q[i].c-q[j].c)));
}
for(int k=1;k<=m;k++)//定义 f(i,j)为i->j的路径上的最大跳的最小值,那么f(i,j)=min( f(i,j), max(f(i,k),f(k,j)) ).
{
for(int i=1;i<=m;i++)
{
for(int j=i+1;j<=m;j++)
if(mp[i][j]>mp[i][k]&&mp[i][j]>mp[k][j])
mp[i][j]=mp[j][i]=max(mp[i][k],mp[k][j]);
}
}
printf("Scenario #%d\nFrog Distance = %.3f\n\n",cnt,mp[1][2]);
}
return 0;
}
后来发现floyd是枚举通过第k个点松弛i,j之间的距离,所以应该写到外层循环。
这里mp[i][j]存的是i,j之间的最长边。
剩下的做法还有dijkstra,spfa,kruskal,prim。。。
很蓝瘦,不想写了,等过两天再说吧,这里先附上大神的代码:
http://blog.csdn.net/dongshimou/article/details/36489269
prim:
http://www.cnblogs.com/ACShiryu/archive/2011/07/28/2120411.html
其实kruskal和prim的思想差不多,都是建立一个最小生成树,一直到1号点和2号点都在树里面就停止(注意这里一定要停止)。
dijkstra的变形就是把dis[i]数组改为存1到i的所有路径中最长边的最小值,和floyd思想大致差不多,不过dj可以在某次选择时如果2是距1最近的点就可以停止了。
spfa其实就是队列优化的bellman-ford,思想大致同dij,实现方式不同罢了。
唉,啥时候有心情再写一遍吧。
昨天刚写了上面的内容,今天又做了一个非常类似的题,这次鼓起勇气写了spfa,调试的时候还是看了题解。。
不过看题解倒不是因为哪里不会写了,而是把题意搞混了。。今天做的题是poj1797
一看这题,唉,这不和昨天那题一样么,咔咔写出来一发wa,然后怎么改怎么wa,看了题解发现这个题是求给定两点之间的任意路径上的最小值中最大的那一个,而上面那个题是求给定两点的任意路径的最大值中最小的那一个。。刚好相反,有点拗口,自行体会吧。。。好像这种问题还有个统称叫瓶颈路问题。。
#include
#include
#include
#include
#include
#include
#include
还有注意两个输出之间有空行。