• [bzoj]1295: [SCOI2009]最长距离


    原题链接

    1295: 最长距离

    题意

    题目要求的是最远的两个点的距离,要求这两个点在同一个连通块里面。可以去掉障碍物,但是要求去掉的障碍物不能超过T。

    分析

    啥,同个连通块??搜索??
    Boom..
    注意到:

    • 在同一个连通块里面不管如何走,不用去掉障碍物就能拓展距离,记费用为0。
    • 在要去掉障碍物时,我们记费用为1。

    那么,我们就可以用最短路的算法对问题进行求解了。
    枚举每一个点(a,b)为起点:

    1. 在图上跑SPFA,最终得到一个二维的cost数组。
    2. 再枚举另一个点(x,y)作为终点,如果cost[x,y]<=T,更新答案为max{dis(a,b,x,y))}

    实现是简单umm...
    关键是想到最短路吧。

    代码

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <queue>
    #include <cmath>
    #include <algorithm>
     
    using namespace std;
    const int dir[4][2]={{-1,0},{0,-1},{1,0},{0,1}};
    int n,m,t,dis[35][35];
    double ans=-1;
    bool g[35][35],vis[35][35];
    queue <int> qx,qy;
    double cal(int a,int b,int c,int d){
        a=(a-c)*(a-c);
        b=(b-d)*(b-d);
        return sqrt(a+b);
    }
    void spfa(int x,int y);
    void Init();
    void work();
    int main()
    {
        Init();
        work();
        printf("%.6f",ans);
        return 0;
    }
    void Init(){
        scanf("%d%d%d",&n,&m,&t);
        char c;
        for(int i=1;i<=n;i++)
            for(int j=1;j<=m;j++){
                cin>>c;
                if(c=='1')g[i][j]=1;
            }
     
    }
    void work(){
        for(int i=1;i<=n;i++)
            for(int j=1;j<=m;j++){
                spfa(i,j);
                for(int ii=1;ii<=n;ii++)
                    for(int jj=1;jj<=m;jj++)
                        if(dis[ii][jj]<=t)
                            ans=max(ans,cal(i,j,ii,jj));
            }
    }
    void spfa(int x,int y){
        memset(dis,0x3f,sizeof(dis));
        qx.push(x);qy.push(y);
        dis[x][y]=g[x][y];
        while(qx.size()){
            x=qx.front();qx.pop();
            y=qy.front();qy.pop();
            for(int i=0;i<4;i++){
                if(x+dir[i][0]<1||x+dir[i][0]>n)continue;
                if(y+dir[i][1]<1||y+dir[i][1]>m)continue;
                if(dis[x][y]+g[x+dir[i][0]][y+dir[i][1]]<dis[x+dir[i][0]][y+dir[i][1]]){
                    dis[x+dir[i][0]][y+dir[i][1]]=dis[x][y]+g[x+dir[i][0]][y+dir[i][1]];
                    if(!vis[x+dir[i][0]][y+dir[i][1]]){
                        qx.push(x+dir[i][0]);
                        qy.push(y+dir[i][1]);
                    }
                }
            }
        }
    }
    
  • 相关阅读:
    原型设计作业
    20210405-1 案例分析作业
    要命的作业
    20210309-1 准备工作
    20210309-2 阅读任务
    前端用js获取本地文件的内容
    2019春第四周作业
    解决BootStap TreeView插件在 BootStrap4上不兼容问题
    ABP VNEXT使用PUT方法时报”对象已被修改,乐观并发失败“解决方案
    【一步一步入坑ABP VNEXT】安装ABP CLI
  • 原文地址:https://www.cnblogs.com/onglublog/p/9859699.html
Copyright © 2020-2023  润新知