离心率计算
4.1.16 The eccentricity of a vertex v is the the length of the shortest path from that vertex to the furthest vertex from v. The diameter of a graph is the maximum eccentricity of any vertex. The radius of a graph is the smallest eccentricity of any vertex. A center is a vertex whose eccentricity is the radius. Implement the following API:
4.1.18 The girth of a graph is the length of its shortest cycle. If a graph is acyclic, then its girth is infinite. Add a method girth() to GraphProperties that returns the girth of the graph. Hint : Run BFS from each vertex. The shortest cycle containing s is a shortest path from s to some vertex v, plus the edge from v back to s.
题目释义
4.1.16 计算点的离心率,图的直径,半径,中心
4.1.18 计算图的围长
定义
点的离心率:图中任意一点v,v的离心率是图中其他点到v的所有最短路径中最大值。
图的直径:图中所有点的离心率的最大值。
图的半径:图中所有点的离心率的最小值。
图的中心:图中离心率长度等于半径的点。
图的围长:如果图中有环,围长则为所有环的长度的最小值。
算法思路
广度优先路径
因为要计算距离,需要一个数组int[] distTo记录距离。可以和数组 boolean[] marked 进行合并 。
distTo[] 初始值设为-1,表示未被寻访。一旦被寻访到,就改为其到顶点的距离。-
改动
离心率计算,在bfp遍历中增加distTo的赋值即可。
环计算,寻访到一个已经被寻访过的顶点,即说明出现了环。
异常抛出问题还不是很熟练,故未对图非连通的情况进行判别抛出异常
import java.util.*;
public class GraphProperties {
//private懒得写了
int[] distTo; //到顶点的距离
int[] e; //离心率
int[] c; //cycle
int[] edgeTo; //前任(是谁牵着你的手走到这条路?)
int diameter = 0;
int radius = Integer.MAX_VALUE;
int center;
int girth = Integer.MAX_VALUE;
//异常抛出问题还不是很熟练,先不考虑
GraphProperties(Graph G) {
int V = G.V();
distTo = new int[V];
e = new int[V];
c = new int[V];
edgeTo = new int[V];
//遍历所有的顶点,造v棵树
for (int v = 0; v < V; v++) {
bfp(G, v);
}
//找各个最大最小值,各找各妈,各赋各值
for (int v = 0; v < V; v++) {
diameter = e[v] > diameter ? e[v] : diameter;
if (e[v] < radius) {
radius = e[v];
center = v;
}
girth = c[v] < girth ? c[v] : girth;
}
}
//主算法
void bfp(Graph G, int s) {
int eccen = 0;
int cycle = Integer.MAX_VALUE;
for (int v = 0; v < G.V(); v++)
distTo[v] = -1; //初始化为0,表示未被寻访过
distTo[s] = 0;
Queue<Integer> q = new LinkedList<Integer>();
q.offer(s);
while (!q.isEmpty()) {
int v = q.poll();
for (int w : G.adj(v)) {//v是我,w是我的前女友们
if (distTo[w] == -1) { //如果未被寻访过
distTo[w] = distTo[v] + 1; //记录距离
eccen = distTo[w]; //这是深度优先算法,因此最后一个被寻访的深度就是最深的
} else if ( w!= edgeTo[v] ) { //遇到一个寻访过的w,就说明牵着现在老婆的手遇到了前女朋友,人生兜兜转转形成了一个环(前提是你遇到的不是你老婆)
int d = distTo[w] + distTo[v] + 1; //算一下绕了多大的一个圈
cycle = d < cycle ? d : cycle; //记录最小的那个圈,走最小的套路
}
}
}
e[s] = eccen;
c[s] = cycle;
}
// diameter of G 图的直径:图中所有点的离心率的最大值。
public int diameter() {
return diameter;
}
// radius of G 图的半径:图中所有点的离心率的最小值。
public int radius() {
return radius;
}
// center of G 图的中心:图中离心率的最小值所对的顶点。
public int center() {
return center;
}
// grith of G 图的围长:如果图中有环,围长则为所有环的长度的最小值。
public int girth() {
return girth;
}
}
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。