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);
        }
    } 
  • 相关阅读:
    Python学习笔记模式匹配与正则表达式之使用和不使用正则表达式
    关于Jqury的一些杂碎
    客户端验证模型
    导航(摘)
    解决了DIV+CSS一个问题
    购买了新书《Bootstrap用户手册—设计响应式网站》及简介Bootstrap是什么
    博客园的博客页面开通了,今天!
    利用Cmake 将最新版本OBS编译成windows版本。
    C语言无法使用引用,一定要使用怎么办? ------指针的指针做参数
    linux core文件的打开和分析
  • 原文地址:https://www.cnblogs.com/birchtree/p/9858045.html
Copyright © 2011-2022 走看看