使用的数据结构:单链表
dfs
dfs大致模板:
void dfs(int u) { //标记一下u节点 st[u] = true; //访问u的每个子节点 for( int i = h[u]; i != -1; i = ne[i] ){ int j = e[i]; //如果j没有被搜过,一条道走到黑 if(!st[j]) dfs(j); } }
树和图的深度优先遍历 [树的重心]
dfs返回以u为根的子树中的点的数量
算法核心:u点子树中点的数量和非子树连通块的点的数量最大值
设u点为重心
返回当前节点的一个子树的点的数量
当前节点所有点数量求和
记录子树点的最大值
和非子树连通块求最大值
记录最大值的最小值
1 #include<bits/stdc++.h> 2 3 using namespace std; 4 5 const int N = 1e5+10; 6 const int M = 2*N; 7 8 int n, m, idx; 9 int h[N], e[M], ne[M]; 10 11 int ans = N; 12 13 bool st[N]; 14 15 void add(int a, int b) 16 { 17 e[idx] = b; 18 ne[idx] = h[a]; 19 h[a] = idx++; 20 } 21 22 int dfs(int u) 23 { 24 int res = 0; 25 st[u] = true; 26 int sum = 1; 27 for( int i = h[u]; i != -1; i = ne[i] ){ 28 int j = e[i]; 29 if(!st[j]){ 30 int s = dfs(j); 31 sum+=s; 32 res = max(res, s); 33 } 34 } 35 res = max(res, n-sum); 36 ans = min(ans, res); 37 38 return sum; 39 } 40 41 int main() 42 { 43 memset(h, -1, sizeof h); 44 cin>>n; 45 for( int i = 0; i < n-1; i++ ){ 46 int a, b; 47 cin>>a>>b; 48 add(a, b); 49 add(b, a); 50 } 51 dfs(1); 52 cout<<ans<<endl; 53 54 return 0; 55 }
bfs
使用的数据结构:队列
bfs大致模板:
bfs() { 初始化队列 d[1] = 0; while(队列非空){ t = 队头; for(t的每一个临边){ j-<临边; if(j未被拓展过){ d[j] = d[t]+1;//d[j]存储起点到j点的距离 q.push(j);//将j加入队列 } } } }
模板题:树的广度优先遍历 [图中点的层次]
给定一个 n 个点 m 条边的有向图,图中可能存在重边和自环。
所有边的长度都是 1,点的编号为 1~n。
请你求出 1 号点到 n 号点的最短距离,如果从 1 号点无法走到 n 号点,输出 ?1。
第一行包含两个整数 n 和 m。
接下来 m 行,每行包含两个整数 a 和 b,表示存在一条从 a 走到 b 的长度为 1 的边。
输出一个整数,表示 1 号点到 n 号点的最短距离。
1≤n,m≤100000
4 5
1 2
2 3
3 4
1 3
1 4
1
1 #include<bits/stdc++.h> 2 3 using namespace std; 4 5 const int N = 1e5+10; 6 7 int h[N], e[N], ne[N], idx; 8 int d[N]; 9 int n, m; 10 11 void add(int a, int b) 12 { 13 e[idx] = b; 14 ne[idx] = h[a]; 15 h[a] = idx++; 16 } 17 18 int bfs() 19 { 20 queue<int> q; 21 q.push(1); 22 memset(d, -1, sizeof d); 23 d[1] = 0; 24 while(!q.empty()){ 25 int t = q.front(); 26 q.pop(); 27 for( int i = h[t]; i != -1; i = ne[i] ){ 28 int j = e[i]; 29 if(d[j]==-1){ 30 d[j] = d[t]+1; 31 q.push(j); 32 } 33 } 34 } 35 return d[n]; 36 } 37 38 int main() 39 { 40 cin>>n>>m; 41 memset(h, -1, sizeof h); 42 for( int i = 0; i < m; i++ ){ 43 int a, b; 44 cin>>a>>b; 45 add(a, b); 46 } 47 cout<<bfs()<<endl; 48 49 return 0; 50 }
原文:https://www.cnblogs.com/IntroductionToAlgorithms/p/15338372.html