树与图的存储
树是一种特殊的图
邻接矩阵:
适用于稠密图(边数接近顶点数的平方)
g[a][b] 存储边a->b,当a,b两点之间有边时,g[a][b] = 1,如果是一个带权图,那么g数组中存的就是边上的权值。
邻接表:
适用于稀疏图(边数远远小于顶点数的平方)
对于每个点 x,开一个单链表,存储可以 x 可以到达的所有点。
//节点的下标指节点在数组中的位置索引,下标用idx来记录。idx范围从0开始,如果idx==-1表示空。 int h[N];//h[i] 存储的是下标,是编号为 i 的节点的 next节点 的下标 int e[N];// e[i] 的值是编号,是下标为 i 的节点 的 编号 int ne[N]; ne[i] 存储的是下标, 是下标为 i 的 节点 的 next节点的下标 int idx; //插入一条边a→b 头插法 void add(int a, int b) { e[idx] = b, ne[idx] = h[a], h[a] = idx ++ ; }
AcWing 849. Dijkstra求最短路 I
acwing上的 一篇 Dijkstra算法图解
代码如下:
import java.util.*;
public class Main{
static int N =510;
static int n, m;
static int [][] g = new int[N][N]; //邻接矩阵
static int [] dist = new int[N]; //存储原点到各点的最短距离
static boolean[] st = new boolean[N];
public static void main(String[] args){
Scanner sc = new Scanner(System.in);
n = sc.nextInt();
m = sc.nextInt();
for(int i = 1; i <= n; i ++) Arrays.fill(g[i], 0x3f3f);//边的权值最大为10000
while(m -- > 0){
int a = sc.nextInt(), b = sc.nextInt(), c = sc.nextInt();
g[a][b] = Math.min(g[a][b], c); //可能会重边,取权值小的
}
System.out.println(dijkstra());
}
public static int dijkstra(){
Arrays.fill(dist, 0x3f3f);
dist[1] = 0; //第一个点为源点,到自身的距离为 0
//n次遍历
for(int i = 0; i < n; i ++){
int t = -1;//存最短点
for(int j = 1; j <= n; j ++){
if(!st[j] && (t == -1 || dist[t] > dist[j]))
t = j;
} 最短点为 t
st[t] = true; t标记为已找到最短路
更新没标记的点 到 源点的 最短路
for(int j = 1; j <= n; j ++){
dist[j] = Math.min(dist[j], dist[t] + g[t][j]);
}
}
if(dist[n] == 0x3f3f) return -1;
else return dist[n];
}
}
AcWing 1562. 微博转发
代码如下:
import java.util.*;
public class Main{
static int N = 1010, M = 100010;
static int[] h = new int[N];
static int[] e = new int[M];
static int[] ne = new int[M];
static int idx;
static int n, l;
static boolean[] st = new boolean[N];
public static void add(int a, int b){
e[idx] = b;
ne[idx] = h[a];
h[a] = idx ++;
}
public static int bfs(int start){
Queue q = new LinkedList();
Arrays.fill(st,false);
q.offer(start);
st[start] = true;
int res = 0;
for(int i = 0; i < l; i ++){
int sz = q.size();
while(sz -- > 0){
int t = (int)(q.poll());
for(int j = h[t]; j != -1; j = ne[j]){
int x = e[j];
if(!st[x]){
q.offer(x);
st[x] = true;
res ++;
}
}
}
}
return res;
}
public static void main(String[] args){
Scanner sc = new Scanner(System.in);
n = sc.nextInt();
l = sc.nextInt();
Arrays.fill(h, -1);
for(int i = 1; i <= n; i ++){
int cnt = sc.nextInt();
while(cnt -- > 0){
int x = sc.nextInt();
add(x, i);
}
}
int m = sc.nextInt();
while(m -- > 0){
int y = sc.nextInt();
System.out.println(bfs(y));
}
}
}