图算法题目

解图相关题目,必须形成自己的一套描述图的结构(邻接矩阵,邻接表等等)。

1. 图的宽度优先遍历



在这里插入图片描述

宽度优先遍历结果: [ 1 , 2 , 3 , 4 , 6 , 5 ] [ 1 , 2 , 3 , 4 , 6 , 5 ] [1,2,3,4,6,5]

import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.Queue;

//图的宽度优先遍历
public class G_BFS {

	public static class Node{
		public int value;
		public int inDegree;
		public int outDegree;
		public ArrayList<Node>nextNodes;
		public ArrayList<Edge>nextEdges;
		public Node(int value) {
			this.value=value;
			nextNodes=new ArrayList<>();
			nextEdges=new ArrayList<>();
		}
	}
	public static class Edge{
		public int weight;
		public Node fromNode;
		public Node toNode;
		public Edge(int weight,Node from,Node to) {
			this.weight=weight;
			fromNode=from;
			toNode=to;
		}
	}
	public static class Graph{
		HashMap<Integer,Node>nodes;
		HashSet<Edge>edges;
		public Graph() {
			nodes=new HashMap<>();
			edges=new HashSet<>();
		}
	}
	public static Graph createGraph(int[][] graph) {
		if(graph==null)return null;
		Graph G=new Graph();
		for(int i=0;i<graph.length;++i) {
			if(!G.nodes.containsKey(graph[i][1])) {
				G.nodes.put(graph[i][1], new Node(graph[i][1]));
			}
			if(!G.nodes.containsKey(graph[i][2])) {
				G.nodes.put(graph[i][2], new Node(graph[i][2]));
			}
			Edge e=new Edge(graph[i][0],G.nodes.get(graph[i][1]),G.nodes.get(graph[i][2]));
			G.nodes.get(graph[i][1]).outDegree++;
			G.nodes.get(graph[i][2]).inDegree++;
			G.nodes.get(graph[i][1]).nextNodes.add(G.nodes.get(graph[i][2]));
			G.nodes.get(graph[i][1]).nextEdges.add(e);
			G.edges.add(e);
		}

		
		return G;
	}
	public static void G_BFS(Node x){//从节点x开始遍历
		if(x==null)return;
		Queue<Node>q=new LinkedList<>();
		q.add(x);
		HashSet<Node>hashSet=new HashSet<>();
		hashSet.add(x);
		while(!q.isEmpty()) {
			Node cur=q.poll();
			System.out.println(cur.value);
			for(Node node:cur.nextNodes) {
				if(!hashSet.contains(node)) {
					q.add(node);
					hashSet.add(node);
				}
			}
			
		}
	}
	public static void main(String[] args) {
		int[][] graph=new int[][]{{0,1,2},{0,1,3},{0,1,4},{0,2,3},{0,3,4},{0,2,6},{0,3,5}};
		Graph G=createGraph(graph);
		G_BFS(G.nodes.get(1));
	}
	
}

在这里插入图片描述




2. 图的深度优先遍历



在这里插入图片描述

深度优先遍历的结果: [ 1 , 2 , 3 , 4 , 5 , 6 ] [ 1 , 2 , 3 , 4 , 5 , 6 ] [1,2,3,4,5,6]

package demo06;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Set;
import java.util.Stack

public class G_DFS {
	public static class Node{
		public int value;
		public int inDegree;
		public int outDegree;
		public ArrayList<Node>nextNodes;
		public ArrayList<Edge>nextEdges;
		public Node(int value) {
			this.value=value;
			nextNodes=new ArrayList<>();
			nextEdges=new ArrayList<>();
		}
	}
	public static class Edge{
		public int weight;
		public Node fromNode;
		public Node toNode;
		public Edge(int weight,Node from,Node to) {
			this.weight=weight;
			fromNode=from;
			toNode=to;
		}
	}
	public static class Graph{
		HashMap<Integer,Node>nodes;
		HashSet<Edge>edges;
		public Graph() {
			nodes=new HashMap<>();
			edges=new HashSet<>();
		}
	}
	public static Graph createGraph(int[][] graph) {
		if(graph==null)return null;
		Graph G=new Graph();
		for(int i=0;i<graph.length;++i) {
			if(!G.nodes.containsKey(graph[i][1])) {
				G.nodes.put(graph[i][1], new Node(graph[i][1]));
			}
			if(!G.nodes.containsKey(graph[i][2])) {
				G.nodes.put(graph[i][2], new Node(graph[i][2]));
			}
			Edge e=new Edge(graph[i][0],G.nodes.get(graph[i][1]),G.nodes.get(graph[i][2]));
			G.nodes.get(graph[i][1]).outDegree++;
			G.nodes.get(graph[i][2]).inDegree++;
			G.nodes.get(graph[i][1]).nextNodes.add(G.nodes.get(graph[i][2]));
			G.nodes.get(graph[i][1]).nextEdges.add(e);
			G.edges.add(e);
		}

		
		return G;
	}
	public static void G_DFS(Node x) {
		Stack<Node>st=new Stack<>();
		Set<Node>hashSet=new HashSet<>();
		st.push(x);
		System.out.println(x.value);
		hashSet.add(x);
		while(!st.isEmpty()) {
			Node cur=st.pop();
			for(Node node:cur.nextNodes) {
				if(!hashSet.contains(node)) {
					hashSet.add(node);
					st.push(cur);
					st.push(node);
					System.out.println(node.value);
					break;
				}
			}
		}
	}
	public static void main(String[] args) {
		int[][] graph=new int[][]{{0,1,2},{0,1,3},{0,1,4},{0,2,3},{0,3,4},{0,2,6},{0,3,5}};
		Graph G=createGraph(graph);
		G_DFS(G.nodes.get(1));
	}

}

在这里插入图片描述




3. 拓扑排序

只有 有向无环图 (无环图一定有入度为0的顶点)才有拓扑排序。



在这里插入图片描述

package demo06;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.Map;
import java.util.Queue;

import demo06.G_BFS.Graph;


//拓扑排序
public class TopologySort {
	public static class Node{
		public int value;
		public int inDegree;
		public int outDegree;
		public ArrayList<Node>nextNodes;
		public ArrayList<Edge>nextEdges;
		public Node(int value) {
			this.value=value;
			nextNodes=new ArrayList<>();
			nextEdges=new ArrayList<>();
		}
	}
	public static class Edge{
		public int weight;
		public Node fromNode;
		public Node toNode;
		public Edge(int weight,Node from,Node to) {
			this.weight=weight;
			fromNode=from;
			toNode=to;
		}
	}
	public static class Graph{
		HashMap<Integer,Node>nodes;
		HashSet<Edge>edges;
		public Graph() {
			nodes=new HashMap<>();
			edges=new HashSet<>();
		}
	}
	public static Graph createGraph(int[][] graph) {
		if(graph==null)return null;
		Graph G=new Graph();
		for(int i=0;i<graph.length;++i) {
			if(!G.nodes.containsKey(graph[i][1])) {
				G.nodes.put(graph[i][1], new Node(graph[i][1]));
			}
			if(!G.nodes.containsKey(graph[i][2])) {
				G.nodes.put(graph[i][2], new Node(graph[i][2]));
			}
			Edge e=new Edge(graph[i][0],G.nodes.get(graph[i][1]),G.nodes.get(graph[i][2]));
			G.nodes.get(graph[i][1]).outDegree++;
			G.nodes.get(graph[i][2]).inDegree++;
			G.nodes.get(graph[i][1]).nextNodes.add(G.nodes.get(graph[i][2]));
			G.nodes.get(graph[i][1]).nextEdges.add(e);
			G.edges.add(e);
		}

		
		return G;
	}
	public static void TopologySort(Graph G) {
		if(G==null)return;
		Queue<Node>q=new LinkedList<>();
		Map<Node,Integer>map=new HashMap<>();
		for(Node node:G.nodes.values()) {
			map.put(node, node.inDegree);
			if(node.inDegree==0) {
				q.add(node);
			}
		}
		while(!q.isEmpty()) {
			Node cur=q.poll();
			System.out.println(cur.value);
			for(int i=0;i<cur.nextNodes.size();++i) {
				cur.nextNodes.get(i).inDegree--;
				if(cur.nextNodes.get(i).inDegree==0)q.add(cur.nextNodes.get(i));
			}
		}
	}
	public static void main(String[] args) {
		int[][] graph=new int[][]{{0,3,5},{0,2,5},{0,5,1},{0,5,4},{0,1,4},{0,1,6},{0,4,6}};
		Graph G=createGraph(graph);
		TopologySort(G);
	}
}

在这里插入图片描述




4. 最小生成树

讨论的是 无向图



在这里插入图片描述


4.1 K r u s k a l Kruskal Kruskal 算法

可以通过并查集优化 H e l p Help Help 类的两个方法 。

package demo06;

import java.util.ArrayList;
import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.PriorityQueue;
import java.util.Scanner;


//最小生成树算法---Kruskal算法
public class Kruskal {
	public static class Node{
		public int value;
		public int inDegree;
		public int outDegree;
		public ArrayList<Node>nextNodes;
		public ArrayList<Edge>nextEdges;
		public Node(int value) {
			this.value=value;
			nextNodes=new ArrayList<>();
			nextEdges=new ArrayList<>();
		}
	}
	public static class Edge{
		public int weight;
		public Node fromNode;
		public Node toNode;
		public Edge(int weight,Node from,Node to) {
			this.weight=weight;
			fromNode=from;
			toNode=to;
		}
	}
	public static class Graph{
		HashMap<Integer,Node>nodes;
		HashSet<Edge>edges;
		public Graph() {
			nodes=new HashMap<>();
			edges=new HashSet<>();
		}
	}
	public static Graph createGraph(int[][] graph) {
		if(graph==null)return null;
		Graph G=new Graph();
		for(int i=0;i<graph.length;++i) {
			if(!G.nodes.containsKey(graph[i][1])) {
				G.nodes.put(graph[i][1], new Node(graph[i][1]));
			}
			if(!G.nodes.containsKey(graph[i][2])) {
				G.nodes.put(graph[i][2], new Node(graph[i][2]));
			}
			Edge e=new Edge(graph[i][0],G.nodes.get(graph[i][1]),G.nodes.get(graph[i][2]));
			G.nodes.get(graph[i][1]).outDegree++;
			G.nodes.get(graph[i][2]).inDegree++;
			G.nodes.get(graph[i][1]).nextNodes.add(G.nodes.get(graph[i][2]));
			G.nodes.get(graph[i][1]).nextEdges.add(e);
			G.edges.add(e);
		}

		
		return G;
	}
	public static class Compare implements Comparator<Edge>{//比较器
		@Override
		public int compare(Edge o1, Edge o2) {
			return o1.weight-o2.weight;
		}
	}
	public static class Help{
		public Map<Node,ArrayList<Node>>map;//记录每个顶点所属的集合
		public Help(int n,Graph G) {//初始化每个顶点单独属于一个集合
			map=new HashMap<>();
			for(int i=1;i<=n;++i) {
				ArrayList<Node>set=new ArrayList<>();
				set.add(G.nodes.get(i));
				map.put(G.nodes.get(i),set);
			}
			
		}
		public boolean isSameSet(Node a,Node b) {//返回a,b顶点是否属于同一个集合
			return map.get(a)==map.get(b);
		}
		public void union(Node a,Node b) {//将a,b所在的集合合并为同一个集合
			for(Node node:map.get(b)) {
				map.get(a).add(node);
			}
			for(Node node:map.get(b)) {
				map.put(node,map.get(a));
			}
			
		}
	}
	public static ArrayList<Edge> Kruskal(int n,Graph G){
		if(n==0||G==null)return null;
		PriorityQueue<Edge>heap=new PriorityQueue<>(new Compare());
		for(Edge e:G.edges) {
			heap.add(e);
		}
		ArrayList<Edge>list=new ArrayList<>();
		Help help=new Help(n,G);
		HashSet<Node>set=new HashSet<>();
		while(help.map.get(G.nodes.get(1)).size()!=n) {//生成树必须包含全部顶点,node(1)所属集合包含所有的顶点
			Edge e=heap.poll();
			if(!help.isSameSet(e.fromNode, e.toNode)) {
				if(!set.contains(e.fromNode)) {
					set.add(e.fromNode);
				}
				if(!set.contains(e.toNode)) {
					set.add(e.toNode);
				}
				help.union(e.fromNode, e.toNode);
				list.add(e);
			}
		}
		return list;
	}
	public static int minValue(int n,Graph G) {
		ArrayList<Edge>list=Kruskal(n,G);
		int ans=0;
		for(Edge e:list) {
			ans+=e.weight;
		}
		System.out.println("---");
		for(Edge e:list) {
			System.out.println(e.fromNode.value+"---"+e.toNode.value+"   "+e.weight);
		}
		return ans;
	}
	public static void main(String[] args) {
		int n,m;
		Scanner scan=new Scanner(System.in);
		n=scan.nextInt();
		m=scan.nextInt();
		int[][] graph=new int[m][3];
		for(int i=0;i<m;++i) {
			graph[i][1]=scan.nextInt();
			graph[i][2]=scan.nextInt();
			graph[i][0]=scan.nextInt();
		}
		Graph G=createGraph(graph);
		int ans=minValue(n,G);
		System.out.println(ans);
		
	}

}



在这里插入图片描述



4.2 P r i m Prim Prim 算法

无向图是特殊的有向图,我采用图的结构是有向图,对于无向图,只需要将每一条边 e ( v 1 , v 2 , w ) e(v1,v2,w) e(v1,v2,w) 都复制对应的边 e ( v 2 , v 1 , w ) e(v2,v1,w) e(v2,v1,w)

package demo06;
//最小生成树之Prim算法
import java.util.ArrayList;
import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.PriorityQueue;
import java.util.Scanner;
import java.util.Set;

public class Prim {
	public static class Node{
		public int value;
		public int inDegree;
		public int outDegree;
		public ArrayList<Node>nextNodes;
		public ArrayList<Edge>nextEdges;
		public Node(int value) {
			this.value=value;
			nextNodes=new ArrayList<>();
			nextEdges=new ArrayList<>();
		}
	}
	public static class Edge{
		public int weight;
		public Node fromNode;
		public Node toNode;
		public Edge(int weight,Node from,Node to) {
			this.weight=weight;
			fromNode=from;
			toNode=to;
		}
	}
	public static class Graph{
		HashMap<Integer,Node>nodes;
		HashSet<Edge>edges;
		public Graph() {
			nodes=new HashMap<>();
			edges=new HashSet<>();
		}
	}
	public static Graph createGraph(int[][] graph) {
		if(graph==null)return null;
		Graph G=new Graph();
		for(int i=0;i<graph.length;++i) {
			if(!G.nodes.containsKey(graph[i][1])) {
				G.nodes.put(graph[i][1], new Node(graph[i][1]));
			}
			if(!G.nodes.containsKey(graph[i][2])) {
				G.nodes.put(graph[i][2], new Node(graph[i][2]));
			}
			Edge e=new Edge(graph[i][0],G.nodes.get(graph[i][1]),G.nodes.get(graph[i][2]));
			G.nodes.get(graph[i][1]).outDegree++;
			G.nodes.get(graph[i][2]).inDegree++;
			G.nodes.get(graph[i][1]).nextNodes.add(G.nodes.get(graph[i][2]));
			G.nodes.get(graph[i][1]).nextEdges.add(e);
			G.edges.add(e);
		}

		
		return G;
	}
	public static class Compare implements Comparator<Edge>{//比较器
		@Override
		public int compare(Edge o1, Edge o2) {
			return o1.weight-o2.weight;
		}
	}
	
	public static ArrayList<Edge> Prim(int n,Graph G){
		if(n==0||G==null)return null;
		ArrayList<Edge>list=new ArrayList<>();
		PriorityQueue<Edge>heap=new PriorityQueue<>(new Compare());
		Set<Node>set=new HashSet<>();
		Node node=G.nodes.get(1);
		set.add(node);
		for(Edge e:node.nextEdges) {
			heap.add(e);
		}
		while(!heap.isEmpty()&&set.size()!=n) {
			Edge e=heap.poll();
			if(!set.contains(e.toNode)) {
				set.add(e.toNode);
				list.add(e);
				for(Edge edge:e.toNode.nextEdges) {
					heap.add(edge);
				}
			}
		}
		return list;
	}
	public static int minValue(int n,Graph G) {
		ArrayList<Edge>list=Prim(n,G);
		int ans=0;
		for(Edge e:list) {
			ans+=e.weight;
		}
		System.out.println("---");
		for(Edge e:list) {
			System.out.println(e.fromNode.value+"---"+e.toNode.value+"   "+e.weight);
		}
		return ans;
	}
	public static void main(String[] args) {
		int n,m;
		Scanner scan=new Scanner(System.in);
		n=scan.nextInt();
		m=scan.nextInt();
		int[][] graph=new int[2*m][3];//无向图
		for(int i=0;i<m;++i) {
			graph[i][1]=scan.nextInt();
			graph[i][2]=scan.nextInt();
			graph[i][0]=scan.nextInt();
			graph[m+i][0]=graph[i][0];
			graph[m+i][1]=graph[i][2];
			graph[m+i][2]=graph[i][1];
		}
		Graph G=createGraph(graph);
		int ans=minValue(n,G);
		System.out.println(ans);
		
	}

}

在这里插入图片描述



4.3 最小生成树题目

在这里插入图片描述
在这里插入图片描述

K r u s k a l Kruskal Kruskal 算法解题

import java.util.*;


public class Solution {
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     *
     * 返回最小的花费代价使得这n户人家连接起来
     * @param n int n户人家的村庄
     * @param m int m条路
     * @param cost int二维数组 一维3个参数,表示连接1个村庄到另外1个村庄的花费的代价
     * @return int
     */
    public static class Node{
		public int value;
		public int inDegree;
		public int outDegree;
		public ArrayList<Node>nextNodes;
		public ArrayList<Edge>nextEdges;
		public Node(int value) {
			this.value=value;
			nextNodes=new ArrayList<>();
			nextEdges=new ArrayList<>();
		}
	}
	public static class Edge{
		public int weight;
		public Node fromNode;
		public Node toNode;
		public Edge(int weight,Node from,Node to) {
			this.weight=weight;
			fromNode=from;
			toNode=to;
		}
	}
	public static class Graph{
		HashMap<Integer,Node>nodes;
		HashSet<Edge>edges;
		public Graph() {
			nodes=new HashMap<>();
			edges=new HashSet<>();
		}
	}
	public static Graph createGraph(int[][] graph) {
		if(graph==null)return null;
		Graph G=new Graph();
		for(int i=0;i<graph.length;++i) {
			if(!G.nodes.containsKey(graph[i][1])) {
				G.nodes.put(graph[i][1], new Node(graph[i][1]));
			}
			if(!G.nodes.containsKey(graph[i][2])) {
				G.nodes.put(graph[i][2], new Node(graph[i][2]));
			}
			Edge e=new Edge(graph[i][0],G.nodes.get(graph[i][1]),G.nodes.get(graph[i][2]));
			G.nodes.get(graph[i][1]).outDegree++;
			G.nodes.get(graph[i][2]).inDegree++;
			G.nodes.get(graph[i][1]).nextNodes.add(G.nodes.get(graph[i][2]));
			G.nodes.get(graph[i][1]).nextEdges.add(e);
			G.edges.add(e);
		}

		
		return G;
	}
	public static class Compare implements Comparator<Edge>{//比较器
		@Override
		public int compare(Edge o1, Edge o2) {
			return o1.weight-o2.weight;
		}
	}
	public static class Help{
		public Map<Node,ArrayList<Node>>map;//记录每个顶点所属的集合
		public Help(int n,Graph G) {//初始化每个顶点单独属于一个集合
			map=new HashMap<>();
			for(int i=1;i<=n;++i) {
				ArrayList<Node>set=new ArrayList<>();
				set.add(G.nodes.get(i));
				map.put(G.nodes.get(i),set);
			}
			
		}
		public boolean isSameSet(Node a,Node b) {//返回a,b顶点是否属于同一个集合
			return map.get(a)==map.get(b);
		}
		public void union(Node a,Node b) {//将a,b所在的集合合并为同一个集合
			for(Node node:map.get(b)) {
				map.get(a).add(node);
			}
			for(Node node:map.get(b)) {
				map.put(node,map.get(a));
			}
			
		}
	}
	public static ArrayList<Edge> Kruskal(int n,Graph G){
		if(n==0||G==null)return null;
		PriorityQueue<Edge>heap=new PriorityQueue<>(new Compare());
		for(Edge e:G.edges) {
			heap.add(e);
		}
		ArrayList<Edge>list=new ArrayList<>();
		Help help=new Help(n,G);
		HashSet<Node>set=new HashSet<>();
		while(help.map.get(G.nodes.get(1)).size()!=n) {//生成树必须包含全部顶点,node(1)所属集合包含所有的顶点
			Edge e=heap.poll();
			if(!help.isSameSet(e.fromNode, e.toNode)) {
				if(!set.contains(e.fromNode)) {
					set.add(e.fromNode);
				}
				if(!set.contains(e.toNode)) {
					set.add(e.toNode);
				}
				help.union(e.fromNode, e.toNode);
				list.add(e);
			}
		}
		return list;
	}
	public static int minValue(int n,Graph G) {
		ArrayList<Edge>list=Kruskal(n,G);
		int ans=0;
		for(Edge e:list) {
			ans+=e.weight;
		}
		System.out.println("---");
		for(Edge e:list) {
			System.out.println(e.fromNode.value+"---"+e.toNode.value+"   "+e.weight);
		}
		return ans;
	}
    public int miniSpanningTree (int n, int m, int[][] cost) {
        // write code here
        for(int i=0;i<m;++i){
            int[] tmp=new int[]{cost[i][2],cost[i][0],cost[i][1]};
            cost[i]=tmp;
        }
        Graph G=createGraph(cost);
       
		int ans=minValue(n,G);
        return ans;
    }
}

在这里插入图片描述



$Prim$ 算法解题
import java.util.*;


public class Solution {
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     *
     * 返回最小的花费代价使得这n户人家连接起来
     * @param n int n户人家的村庄
     * @param m int m条路
     * @param cost int二维数组 一维3个参数,表示连接1个村庄到另外1个村庄的花费的代价
     * @return int
     */
   public static class Node{
		public int value;
		public int inDegree;
		public int outDegree;
		public ArrayList<Node>nextNodes;
		public ArrayList<Edge>nextEdges;
		public Node(int value) {
			this.value=value;
			nextNodes=new ArrayList<>();
			nextEdges=new ArrayList<>();
		}
	}
	public static class Edge{
		public int weight;
		public Node fromNode;
		public Node toNode;
		public Edge(int weight,Node from,Node to) {
			this.weight=weight;
			fromNode=from;
			toNode=to;
		}
	}
	public static class Graph{
		HashMap<Integer,Node>nodes;
		HashSet<Edge>edges;
		public Graph() {
			nodes=new HashMap<>();
			edges=new HashSet<>();
		}
	}
	public static Graph createGraph(int[][] graph) {
		if(graph==null)return null;
		Graph G=new Graph();
		for(int i=0;i<graph.length;++i) {
			if(!G.nodes.containsKey(graph[i][1])) {
				G.nodes.put(graph[i][1], new Node(graph[i][1]));
			}
			if(!G.nodes.containsKey(graph[i][2])) {
				G.nodes.put(graph[i][2], new Node(graph[i][2]));
			}
			Edge e=new Edge(graph[i][0],G.nodes.get(graph[i][1]),G.nodes.get(graph[i][2]));
			G.nodes.get(graph[i][1]).outDegree++;
			G.nodes.get(graph[i][2]).inDegree++;
			G.nodes.get(graph[i][1]).nextNodes.add(G.nodes.get(graph[i][2]));
			G.nodes.get(graph[i][1]).nextEdges.add(e);
			G.edges.add(e);
		}

		
		return G;
	}
	public static class Compare implements Comparator<Edge>{//比较器
		@Override
		public int compare(Edge o1, Edge o2) {
			return o1.weight-o2.weight;
		}
	}
	
	public static ArrayList<Edge> Prim(int n,Graph G){
		if(n==0||G==null)return null;
		ArrayList<Edge>list=new ArrayList<>();
		PriorityQueue<Edge>heap=new PriorityQueue<>(new Compare());
		Set<Node>set=new HashSet<>();
		Node node=G.nodes.get(1);
		set.add(node);
		for(Edge e:node.nextEdges) {
			heap.add(e);
		}
		while(!heap.isEmpty()&&set.size()!=n) {
			Edge e=heap.poll();
			if(!set.contains(e.toNode)) {
				set.add(e.toNode);
				list.add(e);
				for(Edge edge:e.toNode.nextEdges) {
					heap.add(edge);
				}
			}
		}
		return list;
	}
	public static int minValue(int n,Graph G) {
		ArrayList<Edge>list=Prim(n,G);
		int ans=0;
		for(Edge e:list) {
			ans+=e.weight;
		}
	
		return ans;
	}
    public int miniSpanningTree (int n, int m, int[][] cost) {
        // write code here
        for(int i=0;i<m;++i){
            int[] tmp=new int[]{cost[i][2],cost[i][0],cost[i][1]};
            cost[i]=tmp;
        }
        int[][] c=new int[2*m][3];
        for(int i=0;i<m;++i) {
			c[i][0]=cost[i][0];
            c[i][1]=cost[i][1];
            c[i][2]=cost[i][2];
			c[m+i][0]=c[i][0];
			c[m+i][1]=c[i][2];
			c[m+i][2]=c[i][1];
		}
		Graph G=createGraph(c);
		int ans=minValue(n,G);
        
        return ans;
    }
}

在这里插入图片描述

4.4 道路建设

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

import java.util.ArrayList;
import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.PriorityQueue;
import java.util.Scanner;


//最小生成树算法---Kruskal算法
public class Main {
	public static class Node{
		public int value;
		public int inDegree;
		public int outDegree;
		public ArrayList<Node>nextNodes;
		public ArrayList<Edge>nextEdges;
		public Node(int value) {
			this.value=value;
			nextNodes=new ArrayList<>();
			nextEdges=new ArrayList<>();
		}
	}
	public static class Edge{
		public int weight;
		public Node fromNode;
		public Node toNode;
		public Edge(int weight,Node from,Node to) {
			this.weight=weight;
			fromNode=from;
			toNode=to;
		}
	}
	public static class Graph{
		HashMap<Integer,Node>nodes;
		HashSet<Edge>edges;
		public Graph() {
			nodes=new HashMap<>();
			edges=new HashSet<>();
		}
	}
	public static Graph createGraph(int[][] graph) {
		if(graph==null)return null;
		Graph G=new Graph();
		for(int i=0;i<graph.length;++i) {
			if(!G.nodes.containsKey(graph[i][1])) {
				G.nodes.put(graph[i][1], new Node(graph[i][1]));
			}
			if(!G.nodes.containsKey(graph[i][2])) {
				G.nodes.put(graph[i][2], new Node(graph[i][2]));
			}
			Edge e=new Edge(graph[i][0],G.nodes.get(graph[i][1]),G.nodes.get(graph[i][2]));
			G.nodes.get(graph[i][1]).outDegree++;
			G.nodes.get(graph[i][2]).inDegree++;
			G.nodes.get(graph[i][1]).nextNodes.add(G.nodes.get(graph[i][2]));
			G.nodes.get(graph[i][1]).nextEdges.add(e);
			G.edges.add(e);
		}

		
		return G;
	}
	public static class Compare implements Comparator<Edge>{//比较器
		@Override
		public int compare(Edge o1, Edge o2) {
			return o1.weight-o2.weight;
		}
	}
	public static class Help{
		public Map<Node,ArrayList<Node>>map;//记录每个顶点所属的集合
		public Help(int n,Graph G) {//初始化每个顶点单独属于一个集合
			map=new HashMap<>();
			for(int i=1;i<=n;++i) {
				ArrayList<Node>set=new ArrayList<>();
				set.add(G.nodes.get(i));
				map.put(G.nodes.get(i),set);
			}
			
		}
		public boolean isSameSet(Node a,Node b) {//返回a,b顶点是否属于同一个集合
			return map.get(a)==map.get(b);
		}
		public void union(Node a,Node b) {//将a,b所在的集合合并为同一个集合
			for(Node node:map.get(b)) {
				map.get(a).add(node);
			}
			for(Node node:map.get(b)) {
				map.put(node,map.get(a));
			}
			
		}
	}
	public static ArrayList<Edge> Kruskal(int n,Graph G){
		if(n==0||G==null)return null;
		PriorityQueue<Edge>heap=new PriorityQueue<>(new Compare());
		for(Edge e:G.edges) {
			heap.add(e);
		}
		ArrayList<Edge>list=new ArrayList<>();
		Help help=new Help(n,G);
		HashSet<Node>set=new HashSet<>();
		while(help.map.get(G.nodes.get(1)).size()!=n) {//生成树必须包含全部顶点,node(1)所属集合包含所有的顶点
			Edge e=heap.poll();
			if(!help.isSameSet(e.fromNode, e.toNode)) {
				if(!set.contains(e.fromNode)) {
					set.add(e.fromNode);
				}
				if(!set.contains(e.toNode)) {
					set.add(e.toNode);
				}
				help.union(e.fromNode, e.toNode);
				list.add(e);
			}
		}
		return list;
	}
	public static int minValue(int n,Graph G) {
		ArrayList<Edge>list=Kruskal(n,G);
		int ans=0;
		for(Edge e:list) {
			ans+=e.weight;
		}
		return ans;
	}
	public static void main(String[] args) {
		int c,m,n;
		Scanner scan=new Scanner(System.in);
        c=scan.nextInt();
        m=scan.nextInt();
		n=scan.nextInt();
		
		int[][] graph=new int[m][3];
		for(int i=0;i<m;++i) {
			graph[i][1]=scan.nextInt();
			graph[i][2]=scan.nextInt();
			graph[i][0]=scan.nextInt();
		}
		Graph G=createGraph(graph);
		int ans=minValue(n,G);
        if(ans<=c)
		    System.out.println("Yes");
        else
            System.out.println("No");
		
	}

}

在这里插入图片描述




5. 单源最短路( D i j k s t r a Dijkstra Dijkstra 算法)

在学术上要求不能出现 负数环 ,但实际上处理的一般是 正数 权值边的图 。

在这里插入图片描述

package demo06;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Scanner;

import demo06.G_BFS.Graph;

public class Dijkstra {
	public static class Node{
		public int value;
		public int inDegree;
		public int outDegree;
		public ArrayList<Node>nextNodes;
		public ArrayList<Edge>nextEdges;
		public Node(int value) {
			this.value=value;
			nextNodes=new ArrayList<>();
			nextEdges=new ArrayList<>();
		}
	}
	public static class Edge{
		public int weight;
		public Node fromNode;
		public Node toNode;
		public Edge(int weight,Node from,Node to) {
			this.weight=weight;
			fromNode=from;
			toNode=to;
		}
	}
	public static class Graph{
		HashMap<Integer,Node>nodes;
		HashSet<Edge>edges;
		public Graph() {
			nodes=new HashMap<>();
			edges=new HashSet<>();
		}
	}
	public static Graph createGraph(int[][] graph) {
		if(graph==null)return null;
		Graph G=new Graph();
		for(int i=0;i<graph.length;++i) {
			if(!G.nodes.containsKey(graph[i][1])) {
				G.nodes.put(graph[i][1], new Node(graph[i][1]));
			}
			if(!G.nodes.containsKey(graph[i][2])) {
				G.nodes.put(graph[i][2], new Node(graph[i][2]));
			}
			Edge e=new Edge(graph[i][0],G.nodes.get(graph[i][1]),G.nodes.get(graph[i][2]));
			G.nodes.get(graph[i][1]).outDegree++;
			G.nodes.get(graph[i][2]).inDegree++;
			G.nodes.get(graph[i][1]).nextNodes.add(G.nodes.get(graph[i][2]));
			G.nodes.get(graph[i][1]).nextEdges.add(e);
			G.edges.add(e);
		}

		
		return G;
	}
	public static HashMap<Node,Integer> Dijkstra(Node x,int n,Graph G){//从顶点x开始
		HashMap<Node,Integer>distanceMap=new HashMap<>();
		HashSet<Node>set=new HashSet<>();//记录已经被访问结束的顶点,不再允许被访问
		distanceMap.put(x, 0);//x-->x距离是0
		Node minNode=x;
		while(minNode!=null) {
			for(Edge e:minNode.nextEdges) {
				Node node=e.toNode;
				if(!distanceMap.containsKey(node)) {
					distanceMap.put(node, distanceMap.get(minNode)+e.weight);
				}
				else {
					distanceMap.put(node, Math.min(distanceMap.get(node), distanceMap.get(minNode)+e.weight));
				}
			}
			set.add(minNode);
			minNode=getMinNode(distanceMap,set);
		}

		return distanceMap;
	}
	public static Node getMinNode(HashMap<Node,Integer> map,HashSet<Node>set) {
		Node minNode=null;
		int min=Integer.MAX_VALUE;
		for(Node node:map.keySet()) {
			if(!set.contains(node)) {
				if(min>=map.get(node)) {
					minNode=node;
					min=map.get(node);
				}
			}
		}
		return minNode;
	}
	public static int getMinDistance(int n,Graph G) {
		HashMap<Node,Integer>map=Dijkstra(G.nodes.get(1),n,G);
		if(!map.containsKey(G.nodes.get(n)))return -1;
		else return map.get(G.nodes.get(n));
	}
	public static void main(String[] args) {
		int n,m;
		Scanner scan=new Scanner(System.in);
		n=scan.nextInt();
		m=scan.nextInt();
		int[][] graph=new int[m][3];
		for(int i=0;i<m;++i) {
			graph[i][1]=scan.nextInt();
			graph[i][2]=scan.nextInt();
			graph[i][0]=scan.nextInt();
		}
		Graph G=createGraph(graph);
		int ans=getMinDistance(n,G);
		System.out.println(ans);
	}

}


在这里插入图片描述



单源最短路题目

在这里插入图片描述
在这里插入图片描述

import java.util.*;


public class Solution {
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     *
     * 
     * @param n int 顶点数
     * @param m int 边数
     * @param graph int二维数组 一维3个数据,表示顶点到另外一个顶点的边长度是多少​
     * @return int
     */
    public static class Node{
		public int value;
		public int inDegree;
		public int outDegree;
		public ArrayList<Node>nextNodes;
		public ArrayList<Edge>nextEdges;
		public Node(int value) {
			this.value=value;
			nextNodes=new ArrayList<>();
			nextEdges=new ArrayList<>();
		}
	}
	public static class Edge{
		public int weight;
		public Node fromNode;
		public Node toNode;
		public Edge(int weight,Node from,Node to) {
			this.weight=weight;
			fromNode=from;
			toNode=to;
		}
	}
	public static class Graph{
		HashMap<Integer,Node>nodes;
		HashSet<Edge>edges;
		public Graph() {
			nodes=new HashMap<>();
			edges=new HashSet<>();
		}
	}
	public static Graph createGraph(int[][] graph) {
		if(graph==null)return null;
		Graph G=new Graph();
		for(int i=0;i<graph.length;++i) {
			if(!G.nodes.containsKey(graph[i][1])) {
				G.nodes.put(graph[i][1], new Node(graph[i][1]));
			}
			if(!G.nodes.containsKey(graph[i][2])) {
				G.nodes.put(graph[i][2], new Node(graph[i][2]));
			}
			Edge e=new Edge(graph[i][0],G.nodes.get(graph[i][1]),G.nodes.get(graph[i][2]));
			G.nodes.get(graph[i][1]).outDegree++;
			G.nodes.get(graph[i][2]).inDegree++;
			G.nodes.get(graph[i][1]).nextNodes.add(G.nodes.get(graph[i][2]));
			G.nodes.get(graph[i][1]).nextEdges.add(e);
			G.edges.add(e);
		}

		
		return G;
	}
	public static HashMap<Node,Integer> Dijkstra(Node x,int n,Graph G){//从顶点x开始
		HashMap<Node,Integer>distanceMap=new HashMap<>();
		HashSet<Node>set=new HashSet<>();//记录已经被访问结束的顶点,不再允许被访问
		distanceMap.put(x, 0);//x-->x距离是0
		Node minNode=x;
		while(minNode!=null) {
			for(Edge e:minNode.nextEdges) {
				Node node=e.toNode;
				if(!distanceMap.containsKey(node)) {
					distanceMap.put(node, distanceMap.get(minNode)+e.weight);
				}
				else {
					distanceMap.put(node, Math.min(distanceMap.get(node), distanceMap.get(minNode)+e.weight));
				}
			}
			set.add(minNode);
			minNode=getMinNode(distanceMap,set);
		}

		return distanceMap;
	}
	public static Node getMinNode(HashMap<Node,Integer> map,HashSet<Node>set) {
		Node minNode=null;
		int min=Integer.MAX_VALUE;
		for(Node node:map.keySet()) {
			if(!set.contains(node)) {
				if(min>=map.get(node)) {
					minNode=node;
					min=map.get(node);
				}
			}
		}
		return minNode;
	}
	public static int getMinDistance(int n,Graph G) {
		HashMap<Node,Integer>map=Dijkstra(G.nodes.get(1),n,G);
		if(!map.containsKey(G.nodes.get(n)))return -1;
		else return map.get(G.nodes.get(n));
	}
    public int findShortestPath (int n, int m, int[][] graph) {
        // write code here
        
		for(int i=0;i<m;++i) {
            int[] tmp=new int[3];
            tmp[0]=graph[i][2];
            tmp[1]=graph[i][0];
            tmp[2]=graph[i][1];
			graph[i]=tmp;
		}
		Graph G=createGraph(graph);
		int ans=getMinDistance(n,G);
        return ans;
    }
}

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值