package com.example.meitu.data.graph;
import android.util.Log;
import java.util.LinkedList;
/**
* @author zpb
* Created by meitu on 2019/3/18.
* 最短滤镜算法
*/
public class DijkstraDemoGraph {
int v;
LinkedList<Edge>[] adjs;
public DijkstraDemoGraph(int v) {
this.v = v;
for (int i = 0; i < v; i++) {
adjs[i] = new LinkedList();
}
}
public void addEdge(int s, int e, int w) {
adjs[s].push(new Edge(s, e, w));
}
/**
* 边
*/
class Edge {
/**
* 起点
*/
public int s;
/**
* 终点
*/
public int t;
// 权重
public int w;
public Edge(int s, int t, int w) {
this.s = s;
this.t = t;
this.w = w;
}
}
/**
* 从起点到当前点的最小距离
*/
class Vertex {
int id;
int dis;
public Vertex(int id, int dis) {
this.id = id;
this.dis = dis;
}
}
/**
* 循环队列
*/
class PriorQueue {
int v;
Vertex[] nodes;
int head;
int tail;
int index = 0;
PriorQueue(int v) {
//
this.v = v;
nodes = new Vertex[v + 1];
head = 0;
tail = 0;
}
public void add(Vertex vertex) {
if ((tail + 1) % v == head) {
return;
}
nodes[tail + 1] = vertex;
}
public Vertex poll() {
if (head == tail) {
return null;
}
Vertex vertex = nodes[head];
head = (head + 1) % v;
return vertex;
}
public void update(Vertex vertex) {
if (head == tail) {
return;
}
int i = head;
while (i != tail) {
if (nodes[i].id == vertex.id) {
nodes[i] = vertex;
break;
}
i = (i + 1) % v;
}
}
public boolean isEmpty() {
return head == tail;
}
}
public void dijkstra(int s, int e) {
int[] process = new int[v];
PriorQueue mQueue = new PriorQueue(v);
/**
* 是否已经在队列
*/
boolean[] inqueue = new boolean[v];
Vertex[] vertices = new Vertex[v];
//初始化开头
for (int i = 0; i < v; i++) {
vertices[i].dis = Integer.MAX_VALUE;
vertices[i].id = i;
}
//起点入队列
mQueue.add(vertices[s]);
inqueue[s] = true;
while (!mQueue.isEmpty()){
Vertex minVertex = mQueue.poll();
if(minVertex.id == e){
break;
}
//找出临接的边
LinkedList<Edge> edges = adjs[minVertex.id];
for(int i = 0 ; i <edges.size();i++){
Edge edge = edges.get(i);
Vertex nextVertex = vertices[edge.t];
if(minVertex.dis + edge.w < nextVertex.dis){
nextVertex.dis = minVertex.dis +edge.w;
process[nextVertex.id] = minVertex.id;
if(inqueue[nextVertex.id]){
mQueue.update(nextVertex);
}else {
mQueue.add(nextVertex);
inqueue[nextVertex.id] = true;
}
}
}
}
print(s,e,process);
}
private void print(int s,int e,int[] process){
if(s == e)return;
print(s,process[e],process);
Log.d("zpb","-->"+e);
}
}