zoukankan      html  css  js  c++  java
  • POJ 1383题解(树的直径)(BFS)

    题面

    Labyrinth
    Time Limit: 2000MS Memory Limit: 32768K
    Total Submissions: 4997 Accepted: 1861
    Description

    The northern part of the Pyramid contains a very large and complicated labyrinth. The labyrinth is divided into square blocks, each of them either filled by rock, or free. There is also a little hook on the floor in the center of every free block. The ACM have found that two of the hooks must be connected by a rope that runs through the hooks in every block on the path between the connected ones. When the rope is fastened, a secret door opens. The problem is that we do not know which hooks to connect. That means also that the neccessary length of the rope is unknown. Your task is to determine the maximum length of the rope we could need for a given labyrinth.
    Input

    The input consists of T test cases. The number of them (T) is given on the first line of the input file. Each test case begins with a line containing two integers C and R (3 <= C,R <= 1000) indicating the number of columns and rows. Then exactly R lines follow, each containing C characters. These characters specify the labyrinth. Each of them is either a hash mark (#) or a period (.). Hash marks represent rocks, periods are free blocks. It is possible to walk between neighbouring blocks only, where neighbouring blocks are blocks sharing a common side. We cannot walk diagonally and we cannot step out of the labyrinth.
    The labyrinth is designed in such a way that there is exactly one path between any two free blocks. Consequently, if we find the proper hooks to connect, it is easy to find the right path connecting them.
    Output

    Your program must print exactly one line of output for each test case. The line must contain the sentence “Maximum rope length is X.” where Xis the length of the longest path between any two free blocks, measured in blocks.
    Sample Input

    2
    3 3
    ###
    #.#
    ###
    7 6
    #######
    #.#.###
    #.#.###
    #.#.#.#
    #.....#
    #######

    Sample Output

    Maximum rope length is 0.
    Maximum rope length is 8.
    Hint

    Huge input, scanf is recommended.
    If you use recursion, maybe stack overflow. and now C++/c ‘s stack size is larger than G++/gcc
    Source

    Central Europe 1999
    题目大意:在迷宫中找出最长的一条简单路径,求路径长度

    分析:

    此题为树的直径模板题
    树上最长的简单路径即为树的直径。
    求树的直径的方法就是在树上任选一点u,求距离点u最远的点y,再求距离点y最远的点s,点y到点s的距离即为树的直径。

    原理: 设起点为u,第一次BFS找到的终点v一定是树的直径的一个端点
    证明:
    (1) 如果u 是直径上的点,则v显然是直径的终点
    (如果v不是的话,假设直径起点为a,终点为b,又因为u到b的距离小于u到v的距离,那么路径a->u->v比直径更长,这与直径的定义矛盾)
    (2) 如果u不是直径上的点,则u到v必然于树的直径相交(反证法),那么交点到v 必然就是直径的一部分
    综上所述,v一定是直径的一个端点,所以从v进行BFS得到的一定是直径长度

    更详细的证明可以参考http://blog.sina.com.cn/s/blog_dbe928200101cm5t.html

    代码:

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<queue>
    #define maxn 1005
    using namespace std;
    int n,m,t;
    char a[maxn][maxn];
    int used[maxn][maxn];//判重
    const int walkx[4]={1,-1,0,0},walky[4]={0,0,1,-1};//控制走的方向
    struct node{//广搜用结构体
        int x;
        int y;
        int t;
        node(){} 
        node(int xx,int yy,int tim){
            x=xx;
            y=yy;
            t=tim;
        }
    };
    int is_check(int x,int y){//判断下一步是否能走
        if(x<=0||y<=0||x>n||y>m||used[x][y]==1||a[x][y]=='#') return 0;
        else return 1;
    }
    node bfs(int sx,int sy){//sx,sy为起点
        memset(used,0,sizeof(used));
        queue<node>q;
        q.push(node(sx,sy,0));
        node now,nex;
        int tx,ty;
        int maxt=0,maxx=sx,maxy=sy;
        while(!q.empty()){
            now=q.front();
            q.pop();
            if(now.t>maxt){//记录距离最大值
                maxx=now.x;
                maxy=now.y;
                maxt=now.t;
            } 
            for(int i=0;i<4;i++){
                tx=now.x+walkx[i];
                ty=now.y+walky[i];
                if(is_check(tx,ty)){
                    used[tx][ty]=1;
                    q.push(node(tx,ty,now.t+1));
                }
            }
        }
        return node(maxx,maxy,maxt);//返回结构体,可以知道距离任选的一点u最远的点v的位置,方便下次广搜
    }
    int main(){
        char tmp[maxn];
        scanf("%d",&t);
        while(t--){
            scanf("%d %d
    ",&n,&m);
            swap(n,m);
            int xx,yy;
            xx=yy=-1;
            for(int i=1;i<=n;i++){
                scanf("%s",tmp+1);
                for(int j=1;j<=m;j++){
                    a[i][j]=tmp[j];
                    if(a[i][j]=='.'&&xx==-1&&yy==-1){
                        xx=i;//随便选一个点作为起点
                        yy=j;
                    }
                }
    //          getchar();
            }
            node tmp1=bfs(xx,yy);
            node tmp2=bfs(tmp1.x,tmp1.y);
            printf("Maximum rope length is %d.
    ",tmp2.t);
        }
    } 
  • 相关阅读:
    【elasticsearch】关于elasticSearch的基础概念了解【转载】
    【docker】docker容器和宿主机之间文件互传,互相拷贝
    【spring cloud】【docker】使用docker在centOS上部署spring cloud微服务架构服务
    【spring cloud】【IDEA】【Maven】spring cloud多模块打包,打包的jar包只有几k,jar包无法运行,运行报错:no main manifest attribute, in /ms-eureka.jar
    【spring cloud】【IDEA】【maven】spring cloud多模块在idea上使用maven插件打包报错:程序包XXX不存在
    【linux】linux重启tomcat + 实时查看tomcat启动日志
    【linux】linux查看文件大小,磁盘大小,ls命令的使用
    【spring cloud】在spring cloud服务中,打包ms-core失败,报错Failed to execute goal org.springframework.boot:spring-boot-maven-plugin:2.0.4.RELEASE:repackage (default) on project
    【微信小程序】微信小程序 文本过长,自动换行的问题
    【linux】centos7终端中文显示乱码,命令返回中文乱码
  • 原文地址:https://www.cnblogs.com/birchtree/p/9858045.html
Copyright © 2011-2022 走看看