图论刷题记录

记录刷到的然后不咋会的/值得记录的图论题
poj2253
frogger
这个题我觉得挺奇妙的)),大概是我遇到的第一个图论变形题。
基本题意:
有一堆点(编号从1到n),起点和终点分别在1,2上。每个点之间都联通,给出了点的坐标(易得每个点之间的距离)。问怎么走,才能让走过每两个点的距离最小。就是对于任意通路,如何使的每单条路的最大长度最小,这个最小长度就是ans。
举个栗子
如图,
起点为1,终点为2
在这里插入图片描述
那么对于这个图,ans=2。
从起点到终点可以选择从1->2或者1->3->2,第二条路的单条路的最大值为2,比第一条小。

思路:运用Dijkstra算法,对路径进行松弛,dis数组存下起点到该点的最大单条路长度。

const int maxnum=307;
const int inf=0x3f3f3f3f;
int x[maxnum],y[maxnum],n;
double mp[maxnum][maxnum];
double dis[maxnum];
int vis[maxnum];
void dj()
{
    memset(vis,0,sizeof vis);
    for(int i=1; i<=n; i++)
        dis[i]=inf;
    dis[1]=0;
    for(int i=1; i<=n; i++)//合并n个点
    {
        int minn=inf,k;
        for(int j=1; j<=n; j++)
            if(vis[j]==0&&dis[j]<minn)
            {
                k=j;
                minn=dis[j];
            }
        vis[k]=1;
        for(int j=1; j<=n; j++)
            dis[j]=min(dis[j],max(dis[k],mp[k][j]));//dis[j]为从一号石头到第j号石头所有通路中最长边中的最小边
    }
}
int main()
{
    int q=1;
    while(~scanf("%d",&n)&&n)
    {
        memset(mp,0,sizeof mp);
        for(int i=1; i<=n; i++)
            scanf("%d%d",&x[i],&y[i]);
        for(int i=1; i<=n; i++)
            for(int j=i+1; j<=n; j++)
                mp[i][j]=mp[j][i]=sqrt(double(x[i]-x[j])*(x[i]-x[j])+double(y[i]-y[j])*(y[i]-y[j]));
        dj();
        printf("Scenario #%d\nFrog Distance = %.3lf\n\n",q++,dis[2]);
    }
    return 0;
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

KaaaterinaX

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值