解图相关题目,必须形成自己的一套描述图的结构(邻接矩阵,邻接表等等)。
图算法题目
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;
}
}