题目描述

牛牛有一个n个点n条边的连通无向无权图(不存在自环),他现在想删掉图中的一条边使得这个图变为一棵树,并且这棵树树的直径尽可能大,你可以帮帮他吗?
答案输出一个整数,代表删边后可能的最大直径。

示例1

输入

4,[1,2,3,4],[2,3,1,3]

返回值

3

说明

删掉边(1,3)或者(2,3)可以得到最大直径3删掉边(1,3)或者(2,3)可以得到最大直径3删掉边(1,3)或者(2,3)可以得到最大直径3

备注:

3≤n≤5e3

思路:由于点数和变数很小,我们可以枚举要删掉的边,然后按照一般找树的直径的方式找到所有情况中的最大直径即可。

import java.util.*;


public class Solution {
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     * 
     * @param n int整型 
     * @param u int整型一维数组 
     * @param v int整型一维数组 
     * @return int整型
     */
    private int cnt;
    private int[] depth;
    private boolean[] vis;
    private List<List<Integer>> edges;
    public int MaxDiameter (int n, int[] u, int[] v) {
        // write code here
        int ans=0;
        depth=new int[n+1];
        vis=new boolean[n+1];
        edges=new ArrayList<>();
        for(int i=0;i<=n;i++)
            edges.add(new ArrayList<>());
        for(int e=0;e<n;e++){
            edges.clear();
            for(int i=0;i<=n;i++)
                edges.add(new ArrayList<>());
            for(int i=0;i<n;i++){
                if(i==e) continue;
                edges.get(u[i]).add(v[i]);
                edges.get(v[i]).add(u[i]);
            }
            cnt=0;
            Arrays.fill(depth,0);
            Arrays.fill(vis,false);
            dfs(1,0);
            if(cnt!=n) continue;
            int start=1;
            for(int i=1;i<=n;i++)
                if(depth[i]>depth[start])
                    start=i;
            Arrays.fill(depth,0);
            Arrays.fill(vis,false);
            dfs(start,0);
            for(int i=1;i<=n;i++)
                if(depth[i]>depth[start])
                    start=i;
            ans=Math.max(ans,depth[start]-1);
        }
        return ans;
    }
    private void dfs(int u,int f){
        cnt++;
        vis[u]=true;
        depth[u]=Math.max(depth[u],depth[f]+1);
        int size=edges.get(u).size();
        for(int i=0;i<size;i++){
            int v=edges.get(u).get(i);
            if(vis[v]) continue;
            dfs(v,u);
        }
    }
}