• 求树直径及所有直径顶点


    思路: 先从树中任意选择一个顶点。由于树具有任意两个顶点连通的性质,利用DFS或BFS可求出与1距离最远的顶点的集合A,它们都是直径的顶点,但是此时直径长度没有确定、且无法保证求出了所有的直径顶点,需要再次搜索。从第一次搜索所得到的直径顶点中,任意取一个,再次DFS or BFS,得到新的顶点集合B。 将A与B取并集即为所有的直径顶点。(注意:两次搜索即可)

    算法正确性证明参考 : 

    https://blog.csdn.net/wdq347/article/details/9328291

    另外补充: 如果要求图中存在几个不相交环,可以使用并查集。

    以PAT的一道题目为例 : https://pintia.cn/problem-sets/994805342720868352/problems/994805482919673856

    AC 代码 :

     1 #include <iostream>
     2 #include <queue>
     3 #include <set>
     4 #include <vector>
     5 #define Maxsize 10000 + 1
     6 using namespace std;
     7 vector<int> next_p[Maxsize];
     8 set<int> poss;
     9 int find_mid = -1;
    10 int max_dis = -1;
    11 bool vis[Maxsize];
    12 int book[Maxsize];
    13 int find_f(int a){
    14     if(book[a] == a)return a;
    15     else return book[a] = find_f(book[a]);
    16 }
    17 void Union(int a,int b){
    18     int fa = find_f(a);
    19     int fb = find_f(b);
    20     book[fa] = fb;
    21 }
    22 void DFS(int now,int step){
    23     for(vector<int> :: iterator it = next_p[now].begin(); it not_eq next_p[now].end(); it++){
    24         if(vis[*it] == true)continue;
    25         vis[*it] = true;
    26         DFS(*it, step+1);
    27         vis[*it] = false;
    28     }
    29     if(step > max_dis){
    30         poss.clear();
    31         poss.insert(now);
    32         max_dis = step;
    33     }else if(step == max_dis){
    34         poss.insert(now);
    35     }
    36     return;
    37 }
    38 int main(){
    39     int vertex;
    40     cin >> vertex;
    41     for(int i = 1; i <= vertex; i++)book[i] = i;
    42     int cnt = 0;
    43     int pa,pb;
    44     /*        读入边的信息       */
    45     while(cin >> pa >> pb){
    46         Union(pa, pb);  // 并查集合并顶点
    47         next_p[pa].push_back(pb);
    48         next_p[pb].push_back(pa);   // 记录边
    49     }
    50     /*     并查集判断    */
    51     set<int> dict; // 记录
    52     for(int i = 1; i <= vertex; i++){
    53         if(dict.count(find_f(i)))continue;
    54         else {
    55             dict.insert(find_f(i));
    56             cnt++;
    57         }
    58     }
    59     if(cnt not_eq 1){
    60     cout<<"Error: "<<cnt<<" components";
    61     return 0;
    62     }
    63     /*     求解直径顶点    */
    64     vis[1] = true;  // 先选择 1
    65     DFS(1,0);
    66     set<int> ans = poss; // 保留集合A的解
    67     
    68     /*   记得初始化   */
    69     fill(vis, vis+vertex+1, false);
    70     vis[*poss.begin()] = true;
    71     DFS(*poss.begin(),0);
    72     /*   取并集   */
    73     for(set<int> :: iterator it = poss.begin(); it not_eq poss.end(); it++)ans.insert(*it);
    74     
    75     /*     遍历输出,set 自动排序    */
    76     int first = 1;
    77     for(set<int> :: iterator it = ans.begin(); it not_eq ans.end(); it++){
    78         if(first)first = 0;else cout<<endl;
    79         cout<<*it;
    80     }
    81     return 0;
    82 }
    ---- suffer now and live the rest of your life as a champion ----
  • 相关阅读:
    JVM监控工具之JVisualVM
    JMV监控工具之JConsole
    JVM监控工具之jmap、jstat、stack、jps、jstatd、jinfo、jhat、jdb
    深入理解JVM
    Tomcat使用介绍
    性能测试工具之Apache ab
    性能测试工具之WebBench
    Apache监控调优
    Apache配置文件介绍
    Apache工作模式切换
  • 原文地址:https://www.cnblogs.com/popodynasty/p/12129231.html
Copyright © 2020-2023  润新知