zoukankan      html  css  js  c++  java
  • 树的直径(转发自CSDN)

    求树的直径
    树的直径是指树的最长简单路。求法: 两遍BFS :先任选一个起点BFS找到最长路的终点,再从终点进行BFS,则第二次BFS找到的最长路即为树的直径;
                  原理: 设起点为u,第一次BFS找到的终点v一定是树的直径的一个端点
                  证明: 1) 如果u 是直径上的点,则v显然是直径的终点(因为如果v不是的话,则必定存在另一个点w使得u到w的距离更长,则于BFS找到了v矛盾)
                          2) 如果u不是直径上的点,则u到v必然于树的直径相交(反证),那么交点到v 必然就是直径的后半段了
                           所以v一定是直径的一个端点,所以从v进行BFS得到的一定是直径长度
    
                  相关题目有TOJ1056,TOJ3517.
    
    TOJ 1056(Labyrinth):
            大意是一个由‘#’和'.'构成的迷宫,'.'表示可行,‘#’表示不可行,问可行的最长的路的长度是多少。
    view plaincopy to clipboardprint?
    include <cstdio>  
    #include <cstring>  
    #include <queue>  
    #define M 1002  
    using namespace std;  
    int r,c;  
    char map[M][M];  
    bool flag[M][M];  
    int move[4][2]={-1,0,1,0,0,-1,0,1};                                               // 分别表示上下左右  
    int maxt;  
    struct Node{  
            int x,y,num;  
    };  
    Node ans;  
    bool legal(int x,int y){                                                                   //判断该点是否越界及是否可走  
            if(x >=0 && x < r && y>=0 && y < c &&map[x][y]=='.') return true;  
            return false;  
    }  
    void bfs(Node start){  
            memset(flag,false,sizeof(flag));                                               //初始所有点标记为false  
            flag[start.x][start.y] = true;                                                    //起点标记为true  
            queue<Node>f;  
            while(!f.empty()) f.pop();                                                       //清空创建的队列  
            Node m,n,tep;  
            int tx,ty,xx,yy;  
            int i,j,k,num;  
            f.push(start);  
            while(!f.empty()){                                                                   //如果队列不为空  
                    m = f.front();                                                                   //取出队首元素  
                    tx = m.x; ty = m.y; num = m.num;  
                    if(num > maxt){                                                              //如果该元素的长度大于maxt,更新maxt  
                            maxt = num;  
                            ans = m;  
                    }  
                    for(i = 0;i < 4; i++){                                                       //以m为起点向4个方向BFS  
                            xx = tx + move[i][0];  
                            yy = ty + move[i][1];  
                            if(!flag[xx][yy] && legal(xx,yy)){  
                                    flag[xx][yy] = true;  
                                    tep.x = xx;  
                                    tep.y = yy;  
                                    tep.num = num + 1;  
                                    f.push(tep);  
                                    if(num+1>maxt){                                            //如果有更大的则更新  
                                            maxt = num + 1;  
                                            ans = tep;  
                                    }  
                            }  
                    }  
                    f.pop();                                                                               //弹出队首元素  
            }   
    }  
    int main(){  
            int i,j,T;  
            Node start,end;  
            bool mark;  
            scanf("%d",&T);  
            while(T--){  
                    scanf("%d%d",&c,&r);  
                    mark = false; maxt = -1;  
                    for(i = 0;i < r; i++)  
                            scanf("%s",map[i]);  
                    for(i = 0;i < r; i++){  
                            for(j = 0;j < c; j++){  
                                    if(map[i][j]=='.'){                                                     //任选一点BFS  
                                            start.x = i;  
                                            start.y = j;  
                                            start.num = 0;  
                                            bfs(start);  
                                            mark = true;  
                                            break;  
                                    }  
                            }  
                            if(mark) break;  
                    }  
                    maxt = -1;ans.num = 0;                                                           //此时ans一定是直径的端点,将它设为起点  
                    bfs(ans);                                                                                    //进行第二次BFS  
                    printf("Maximum rope length is %d.
    ",maxt);  
            }  
    }  
     
     
    
    TOJ3517(The longest athletic track):
              题目给出了一棵生成树,问这棵生成树最长的路的长度是多少。
    view plaincopy to clipboardprint?
    #include<iostream>  
    #include<queue>  
    #define INF 999999  
    #define M 2002  
    using namespace std;  
    int n;  
    int maxx;  
    int map[M][M],sum[M];  
    bool flag[M];  
    int bfs(int begin){  
                queue<int>f;  
                int i,m,k,key;  
                maxx=0;  
                memset(flag,false,sizeof(flag));  
                f.push(begin);  
                while(!f.empty()){  
                            k=f.front();  
                             for(i=1;i<=n;i++){  
                                     if(map[k][i]!=INF&&!flag[i]){  
                                                flag[i]=true;  
                                                f.push(i);  
                                                sum[i]=sum[k]+map[k][i];  
                                                 if(sum[i]>maxx) { maxx=sum[i];key=i; }  
                                     }  
                             }  
                             f.pop();  
                }  
                return key;  
    }  
    int main()  
    {  
                int i,j,k,dis,key,cas;  
                scanf("%d",&cas);  
                while(cas--){  
                             scanf("%d",&n);  
                             for(i=1;i<n;i++)  
                                       for(j=i+1;j<=n;j++)  
                                                map[i][j]=map[j][i]=INF;  
                             for(i=1;i<n;i++){  
                                       scanf("%d%d%d",&j,&k,&dis);  
                                       map[j][k]=map[k][j]=dis;  
                             }  
                             sum[1]=0;  
                             key=bfs(1);  
                             sum[key]=0;  
                             key=bfs(key);  
                             printf("%d
    ",maxx);  
                 }  
        //system("pause");  
    }  
  • 相关阅读:
    JS原始类型Number数字类型
    JS数据类型基础知识
    JS基础循环语句和跳转语句
    JS对象类型数组方法篇
    JS对象类型数组基础篇
    JS基础逻辑运算符
    IE6,IE7,FF等浏览器不兼容原因及解决办法(转)
    DML、DDL、DCL区别
    Asp.net(c#)GridView分页时用图片显示上一页,下一页
    P3P完成跨域COOKIE
  • 原文地址:https://www.cnblogs.com/zuimeiyujianni/p/8652757.html
Copyright © 2011-2022 走看看