根据题意,求的是最大生成树。利用Kruskal算法,对边进行从大到小的顺序进行排序,然后再依次取出边加入结果集中。假设图有n个顶点,那么,当结果集中有n-1条边时,剩下的边的集合即为反馈边集。
1 package org.xiu68.ch05.ex9; 2 3 import java.util.ArrayList; 4 import java.util.Comparator; 5 6 public class Ex5_21 { 7 8 public static void main(String[] args) { 9 // TODO Auto-generated method stub 10 int[][] edges=new int[][]{ 11 {0,2,1,6}, 12 {2,0,5,3}, 13 {1,5,0,4}, 14 {6,3,4,0} 15 }; 16 ArrayList<String> vexs=new ArrayList<>(); 17 for(int i=0;i<4;i++) 18 vexs.add("v"+i); 19 MGraph<String> m1=new MGraph<String>(4,4,edges,vexs); 20 m1.kruskal(); 21 //运行结果 22 /* 23 (0,3):6 24 (1,2):5 25 (2,3):4 26 (1,3):3 27 (0,1):2 28 (0,2):1 29 ************************************* 30 反馈边集为: 31 (1,3):3 32 (0,1):2 33 (0,2):1 34 */ 35 } 36 } 37 38 //边类型 39 class Edge{ 40 public int head; //头顶点序号 41 public int tail; //尾顶点序号 42 public int cost; //权值 43 44 public Edge(int head, int tail, int cost) { 45 super(); 46 this.head = head; 47 this.tail = tail; 48 this.cost = cost; 49 } 50 } 51 52 //邻接矩阵表示图 53 class MGraph<T> implements Comparator<Edge>{ 54 public int vexNum; //顶点数量 55 public int edgeNum; //边数量 56 public ArrayList<T> vexs; //顶点表 57 public int[][] edges; //邻接矩阵 58 59 public MGraph(int vexNum, int edgeNum, int[][] edges, ArrayList<T> vexs) { 60 this.vexNum = vexNum; 61 this.edgeNum = edgeNum; 62 this.edges = edges; 63 this.vexs=vexs; 64 } 65 66 //返回反馈边集 67 public void kruskal(){ 68 ArrayList<Edge> eds=new ArrayList<>(); 69 //初始化边集数组 70 for(int i=0;i<edges.length;i++){ 71 for(int j=i+1;j<edges[i].length;j++){ 72 if(edges[i][j]==0) 73 continue; 74 Edge e=new Edge(i,j,edges[i][j]); 75 eds.add(e); 76 } 77 } 78 79 //对边集数组进行排序 80 eds.sort(this); 81 82 for(int i=0;i<eds.size();i++) 83 System.out.println("("+eds.get(i).head+","+eds.get(i).tail+"):"+eds.get(i).cost); 84 85 ArrayList<Edge> resultSet=new ArrayList<>(); //存放反馈边集 86 int[] components=new int[vexNum]; //并查集 87 for(int i=0;i<vexNum;i++) 88 components[i]=i; 89 90 int k=0,j=0; 91 while(k<vexNum-1){ 92 93 int h1=eds.get(j).head; 94 int t1=eds.get(j).tail; 95 int com1=components[h1]; 96 int com2=components[t1]; 97 98 //在不同的并查集 99 if(com1!=com2){ 100 k++; 101 for(int i=0;i<vexNum;i++){ 102 if(components[i]==com2) 103 components[i]=com1; 104 } 105 }else{ 106 //反馈边集 107 resultSet.add(eds.get(j)); 108 } 109 j++; 110 } 111 112 //找到n-1条边后,剩下的边也属于反馈边集 113 for(int i=j;i<eds.size();i++) 114 resultSet.add(eds.get(i)); 115 116 System.out.println("*************************************"); 117 System.out.println("反馈边集为:"); 118 for(int i=0;i<resultSet.size();i++) 119 System.out.println("("+resultSet.get(i).head+","+resultSet.get(i).tail+"):"+resultSet.get(i).cost); 120 } 121 122 @Override 123 public int compare(Edge e1, Edge e2) { 124 // TODO Auto-generated method stub 125 //按从大到小排序 126 if(e1.cost<e2.cost) 127 return 1; 128 else 129 return -1; 130 } 131 }