不包括最大流
package graph;
import java.util.*;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.PriorityBlockingQueue;
/**
* Created by chenzhichao on 16/6/2.
*/
public class Graph {
public static final int WHITE = 1;
public static final int GRAY = 2;
public static final int BLACK = 3;
public static int time = 0;
private LinkedBlockingQueue<ListGraphNode> queue = new LinkedBlockingQueue<ListGraphNode>();
public ListGraphNode[] nodeList = new ListGraphNode[100];
public static class ListGraphNode implements Cloneable {
public int position;
public int color = WHITE;
private int begin;
public int finish;
private int d = Integer.MAX_VALUE;
private ListGraphNode pre = null;
private SimpleNode next = null;
public ListGraphNode(int position) {
this.position = position;
}
@Override
protected ListGraphNode clone() throws CloneNotSupportedException {
return (ListGraphNode) (super.clone());
}
}
public static class SimpleNode implements Cloneable {
private int position;
private int weight;
private SimpleNode next = null;
public SimpleNode(int position) {
this.position = position;
}
public SimpleNode(int position, int weight) {
this.position = position;
this.weight = weight;
}
@Override
protected SimpleNode clone() throws CloneNotSupportedException {
return (SimpleNode) (super.clone());
}
}
/**
* 边
*/
public static class Edge implements Comparable {
protected int weight;
protected ListGraphNode from;
protected ListGraphNode to;
public Edge(int weight, ListGraphNode from, ListGraphNode to) {
this.weight = weight;
this.from = from;
this.to = to;
}
public Edge() {
}
@Override
public int compareTo(Object o) {
return weight;
}
}
public void init1() {
ListGraphNode node = new ListGraphNode(1);
node.next = new SimpleNode(2);
node.next.next = new SimpleNode(4);
nodeList[1] = node;
node = new ListGraphNode(2);
node.next = new SimpleNode(5);
nodeList[2] = node;
node = new ListGraphNode(3);
node.next = new SimpleNode(5);
node.next.next = new SimpleNode(6);
nodeList[3] = node;
node = new ListGraphNode(4);
node.next = new SimpleNode(2);
nodeList[4] = node;
node = new ListGraphNode(5);
node.next = new SimpleNode(4);
nodeList[5] = node;
node = new ListGraphNode(6);
node.next = new SimpleNode(6);
nodeList[6] = node;
}
public void init2() {
ListGraphNode node = new ListGraphNode(0);
node.next = new SimpleNode(1, 10);
node.next.next = new SimpleNode(5, 11);
nodeList[0] = node;
node = new ListGraphNode(1);
node.next = new SimpleNode(2, 18);
node.next.next = new SimpleNode(8, 12);
node.next.next.next = new SimpleNode(6, 16);
nodeList[1] = node;
node = new ListGraphNode(2);
node.next = new SimpleNode(8, 8);
node.next.next = new SimpleNode(3, 22);
nodeList[2] = node;
node = new ListGraphNode(3);
node.next = new SimpleNode(8, 21);
node.next.next = new SimpleNode(6, 24);
node.next.next.next = new SimpleNode(7, 16);
node.next.next.next.next = new SimpleNode(4, 20);
nodeList[3] = node;
node = new ListGraphNode(4);
node.next = new SimpleNode(7, 7);
node.next.next = new SimpleNode(5, 26);
nodeList[4] = node;
node = new ListGraphNode(5);
node.next = new SimpleNode(6, 17);
nodeList[5] = node;
node = new ListGraphNode(6);
node.next = new SimpleNode(7, 19);
nodeList[6] = node;
node = new ListGraphNode(7);
nodeList[7] = node;
node = new ListGraphNode(8);
nodeList[8] = node;
}
public void init4(){
ListGraphNode node = new ListGraphNode(0);
node.next = new SimpleNode(1,10);
node.next.next = new SimpleNode(4,5);
nodeList[0] = node;
node = new ListGraphNode(1);
node.next = new SimpleNode(2,1);
node.next.next = new SimpleNode(4,2);
nodeList[1] = node;
node = new ListGraphNode(2);
node.next = new SimpleNode(3,4);
nodeList[2] = node;
node = new ListGraphNode(3);
node.next = new SimpleNode(2,6);
node.next.next = new SimpleNode(0,7);
nodeList[3] = node;
node = new ListGraphNode(4);
node.next = new SimpleNode(2,9);
node.next.next = new SimpleNode(3,2);
node.next.next.next = new SimpleNode(1,3);
nodeList[4] = node;
}
public static class SimpleEdge {
public int weight = Integer.MAX_VALUE;
public int pre = -1;
public SimpleEdge(int weight) {
this.weight = weight;
}
public SimpleEdge() {
}
public SimpleEdge(int weight, int pre) {
this.weight = weight;
this.pre = pre;
}
}
public static SimpleEdge[][] init3() {
SimpleEdge[][] edges = new SimpleEdge[5][5];
edges[0][1] = new SimpleEdge(3, 0);
edges[0][2] = new SimpleEdge(8, 0);
edges[0][4] = new SimpleEdge(-4, 0);
edges[1][4] = new SimpleEdge(7, 1);
edges[1][3] = new SimpleEdge(1, 1);
edges[2][1] = new SimpleEdge(4, 2);
edges[3][0] = new SimpleEdge(2, 3);
edges[3][2] = new SimpleEdge(-5, 3);
edges[4][3] = new SimpleEdge(6, 4);
for (int i = 0; i < 5; i++)
for (int j = 0; j < 5; j++)
if (edges[i][j] == null) {
edges[i][j] = new SimpleEdge();
if (i == j)
edges[i][j].weight = 0;
}
return edges;
}
/**
* 广度优先遍历
* 一个元素出队->遍历操作->他的所有邻接点入队
*/
public void BFS() {
nodeList[1].color = GRAY;
nodeList[1].d = 0;
queue.offer(nodeList[1]);
while (queue.size() != 0) {
ListGraphNode node = queue.poll();
System.out.print(node.position + "***");
SimpleNode next = node.next;
while (next != null) {
ListGraphNode currentNode = nodeList[next.position];
if (currentNode.color == WHITE) {
currentNode.color = GRAY;
currentNode.d = node.d + 1;
currentNode.pre = node;
queue.offer(currentNode);
}
next = next.next;
}
node.color = BLACK;
}
}
/**
* 深度优先遍历
* 对当前点进行遍历操作->对所有邻接点逐个进行深度优先遍历
* 拓扑排序是在深度优先遍历结束后,按finish对节点进行排序(前提:有向无环图)
*/
public void DFS() {
for (ListGraphNode node : nodeList)
if (node != null && node.color == WHITE) {
dfs_visit(node);
System.out.println("*********************");
}
}
public void dfs_visit(ListGraphNode node) {
node.color = GRAY;
node.begin = ++time;
SimpleNode next = node.next;
while (next != null) {
if (nodeList[next.position].color == WHITE)
dfs_visit(nodeList[next.position]);
next = next.next;
}
node.color = BLACK;
node.finish = ++time;
System.out.println(node.position + ",begin = " + node.begin + ",finish = " + node.finish);
}
/**
* 邻接矩阵求转置
*/
public Graph getT() {
ListGraphNode[] newNodeList = new ListGraphNode[nodeList.length];
TreeMap<Integer, List<SimpleNode>> map = new TreeMap<Integer, List<SimpleNode>>();
try {
for (int i = 0; i < nodeList.length; i++) {
if (nodeList[i] != null) {
newNodeList[i] = nodeList[i].clone();
newNodeList[i].next = null;
List<SimpleNode> list = new ArrayList<SimpleNode>();
SimpleNode next = nodeList[i].next;
while (next != null) {
list.add(next.clone());
next = next.next;
}
map.put(i, list);
}
}
for (Map.Entry<Integer, List<SimpleNode>> entry : map.entrySet()) {
for (SimpleNode sn : entry.getValue()) {
sn.next = newNodeList[sn.position].next;
newNodeList[sn.position].next = sn;
sn.position = entry.getKey();
}
}
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
Graph g = new Graph();
g.nodeList = newNodeList;
return g;
}
/**
* 强连通分量
*/
public static void stronglyConnectedComponents(Graph g) {
g.DFS();
System.out.println("+++++++++++++++++++++++");
Graph gt = g.getT();
Graph.ListGraphNode[] temp = Arrays.copyOfRange(g.nodeList, 1, 7);
Arrays.sort(temp, new Comparator<Graph.ListGraphNode>() {
@Override
public int compare(Graph.ListGraphNode o1, Graph.ListGraphNode o2) {
return o2.finish - o1.finish;
}
});
for (ListGraphNode node : gt.nodeList)
if (node != null)
node.color = Graph.WHITE;
for (Graph.ListGraphNode node : temp) {
if (gt.nodeList[node.position].color == Graph.WHITE) {
gt.dfs_visit(gt.nodeList[node.position]);
System.out.println("*********************");
}
}
}
private static ArrayList<Edge> getEdges(Graph g) {
ArrayList<Edge> edges = new ArrayList<Edge>();
for (int i = 0; i < g.nodeList.length; i++)
if (g.nodeList[i] != null) {
SimpleNode next = g.nodeList[i].next;
while (next != null) {
edges.add(new Edge(next.weight, g.nodeList[i], g.nodeList[next.position]));
next = next.next;
}
}
return edges;
}
/**
* 按无向图考虑
*
* @param g
* @return
*/
private static Map<String, Integer> getEdgesMap(Graph g) {
ArrayList<Edge> edges = getEdges(g);
Map<String, Integer> map = new HashMap<String, Integer>();
for (Edge edge : edges) {
map.put(edge.from.position + "|" + edge.to.position, edge.weight);
map.put(edge.to.position + "|" + edge.from.position, edge.weight);//有向图许注释掉此行
}
return map;
}
protected static int find(int[] parent, int f) {
while (parent[f] != 0)
f = parent[f];
return f;
}
public static void kruskal(Graph g) {
ArrayList<Edge> edges = getEdges(g);
edges.sort(new Comparator<Edge>() {
@Override
public int compare(Edge o1, Edge o2) {
return o1.weight - o2.weight;
}
});
int[] parents = new int[g.nodeList.length];
for (Edge edge : edges) {
int beginParent = find(parents, edge.from.position);
int endParent = find(parents, edge.to.position);
if (beginParent != endParent) {
parents[beginParent] = endParent;
System.out.println("from:" + edge.from.position + ",to:" + edge.to.position + ",weight =" + edge.weight);
}
}
}
public static void prim(Graph g, int index) {
PriorityBlockingQueue<ListGraphNode> queue = new PriorityBlockingQueue<ListGraphNode>(1000, new Comparator<ListGraphNode>() {
@Override
public int compare(ListGraphNode o1, ListGraphNode o2) {
return o1.d - o2.d;
}
});
for (int i = 0; i < g.nodeList.length; i++) {
if (g.nodeList[i] != null) {
g.nodeList[i].pre = null;
g.nodeList[i].d = Integer.MAX_VALUE;
queue.offer(g.nodeList[i]);
}
}
g.nodeList[index].d = 0;
Map<String, Integer> edgeMap = getEdgesMap(g);
while (!queue.isEmpty()) {
ListGraphNode node = queue.poll();
for (ListGraphNode nd : queue) {
Integer w = edgeMap.get(node.position + "|" + nd.position);
w = w == null ? Integer.MAX_VALUE : w;
if (nd.d > w) {
queue.remove(nd);
nd.d = w;
nd.pre = node;
queue.offer(nd);
}
}
}
}
public static void relax(ListGraphNode from, ListGraphNode to, Map<String, Integer> map) {
if (from.d != Integer.MAX_VALUE && to.d > from.d + map.get(to.position + "|" + from.position)) {
to.d = from.d + map.get(to.position + "|" + from.position);
to.pre = from;
}
}
public static void initSinggeSource(Graph g, int index) {
for (ListGraphNode nd : g.nodeList) {
if (nd != null) {
nd.d = Integer.MAX_VALUE;
nd.pre = null;
}
}
g.nodeList[index].d = 0;
g.nodeList[index].pre = g.nodeList[index];
}
public static boolean bellmanFord(Graph g) {
ArrayList<Edge> edges = getEdges(g);
Map<String, Integer> map = getEdgesMap(g);
initSinggeSource(g, 0);
for (int i = 1; i < g.nodeList.length; i++)
for (Edge edge : edges)
relax(edge.from, edge.to, map);
for (Edge edge : edges)
if (edge.to.d > edge.from.d + edge.weight)
return false;
return true;
}
public static void floyd(SimpleEdge[][] edges, int n) {
for (int k = 0; k < n; k++)
for (int i = 0; i < n; i++)
for (int j = 0; j < n; j++) {
if (edges[i][k].weight != Integer.MAX_VALUE && edges[k][j].weight != Integer.MAX_VALUE) {
int sum = edges[i][k].weight + edges[k][j].weight;
if (edges[i][j].weight > sum) {
edges[i][j].weight = sum;
edges[i][j].pre = k;
}
}
}
}
private static String makeSinglePath(SimpleEdge[][] edges, int from, int to, String s) {
if (from == edges[from][to].pre) {
if (s.length() != 0) // 此处涉及到cpu执行指令的一个知识,就是判断语句永远把最有可能出现的情况放在if后边而不是else后边,
s = s + "->" + to; // 因为放在else后边涉及到指令跳转,会降低效率
else
s = s + from + "->" + to;
return s;
}
return makeSinglePath(edges, edges[from][to].pre, to, makeSinglePath(edges, from, edges[from][to].pre, s));
}
public static void printPath(SimpleEdge[][] edges, int n) {
for (int i = 0; i < n; i++)
for (int j = 0; j < n; j++)
if (edges[i][j].pre != -1)
System.out.println(i + "到" + j + "路径是:\n" + makeSinglePath(edges, i, j, ""));
}
public static void dijkstra(Graph g, int index) {
Map<String, Integer> map = getEdgesMap(g);
initSinggeSource(g, index);
PriorityQueue<ListGraphNode> queue = new PriorityQueue<ListGraphNode>(new Comparator<ListGraphNode>() {
@Override
public int compare(ListGraphNode o1, ListGraphNode o2) {
return o1.d - o2.d;
}
});
for (ListGraphNode node : g.nodeList)
if (node != null)
queue.add(node);
while (queue.size() != 0) {
ListGraphNode node = queue.poll();
List<ListGraphNode> tempList = new ArrayList<ListGraphNode>();
for (ListGraphNode node1 : queue) {
Integer w = map.get(node.position + "|" + node1.position);
if (w != null && node.d != Integer.MAX_VALUE && (node.d + w) < node1.d) {
node1.d = node.d + w;
node1.pre = node;
tempList.add(node1);
}
}
tempList.forEach((ListGraphNode nd) -> {
queue.remove(nd);
queue.add(nd);
});
}
}
public static void printDijstraPath(Graph g,int index){
for(int i = 0; i < g.nodeList.length;i++){
ListGraphNode node = g.nodeList[i];
if(node != null && node.position != index){
printDsinglePath(g,index,i);
System.out.println();
}
}
}
private static void printDsinglePath(Graph g, int index, int i) {
if(i != index){
printDsinglePath(g, index, g.nodeList[i].pre.position);
System.out.print("->" + i);
}else
System.out.print(i);
}
}