题目描述
牛牛有一个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);
}
}
}