# week7 note
## 數字全排列
``` cpp
#include <bits/stdc++.h>
using namespace std;
int n = 3, m = 2;//n = 3, m = 2
vector<int> v;//vector 的名字是 v
void dfs(int lev, int num) {//召喚dfs
if(lev == m) {
for(int t : v) cout << t << ' ';
cout << endl;//換行
return;
}
for(int i = num + 1; i <= n; i++) {
v.push_back(i);
dfs(lev + 1, i);
v.pop_back();
}
}
int main() {
dfs(0, 0);
}
```
## DFS 判斷 $node_0$ 可不可以走到 $node_{n-1}$
輸入n, m 分別為點的個數(idx為0~n-1), 邊的個數
接下來有m行,每行有兩個數字u, v,代表u可以到v
保證輸入沒有環
$n <= 100$
範例輸入
7 8
0 1
1 2
1 3
2 4
4 0
2 6
5 6
6 4
範例輸出
YES
``` cpp
#include <bits/stdc++.h>
using namespace std;
int G[105][105] {};
bool visit[105];
int n;
void dfs(int idx) {
if(visit[idx]) return;
visit[idx] = 1;
for(int i = 0; i < n; i++) { //每次新的idx對全部的數字搜尋有沒有路
if(G[idx][i] == 1) { //如果某一條有路以新數作為idx往下
dfs(i);
}
}
}
int main() {
int m;
cin >> n >> m;
for(int i = 0; i < m; i++) {
int u, v;
cin >> u >> v;
G[u][v] = 1;
}
dfs(0);
if(visit[n-1]) cout << "YES\n";
else cout << "NO\n";
}
```
## dfs 找到 0 ~ n-1 的所有路徑
輸入和前面一樣
7 8
0 1
1 2
1 3
2 4
0 4
2 6
6 5
6 4
``` cpp
#include <bits/stdc++.h>
using namespace std;
int G[105][105] {};
bool visit[105];
int n;
vector<int> path;
void dfs(int idx) {
if(idx == n-1) {
for(int u : path) cout << u << ' ';
cout << endl;
}
for(int i = 0; i < n; i++) if(G[idx][i] == 1) {
path.push_back(i);
dfs(i);
path.pop_back();
}
}
int main() {
int m;
cin >> n >> m;
for(int i = 0; i < m; i++) {
int u, v;
cin >> u >> v;
G[u][v] = 1;
}
dfs(0);
}
```
## 給你一張圖判斷是不是樹
=> 找看看有沒有環
=> dfs如果走到父節點以外重複的點,就是有環!!
``` cpp
bool circle = false;
void dfs(int idx) {
if(visit[idx]) circle = true;
// your code
}
```
## 找樹的深度
``` cpp
int depth[105]{};
void dfs(int lev, int idx) {
depth[idx] = lev;
.
.
dfs(lev + 1, i)
.
}
```
## 找子樹大小(以x為根結點的子樹節點樹)
``` cpp
const int maxn = 1e5 + 50;
vector<int> G[100005];
bool visit[105];
int subtree_size[maxn];
void dfs(int idx, int par) {
subtree_size[idx] = 1;
for(int u : G[idx]) if(u != par){
dfs(u);
subtree_size[idx] += subtree_size[u];
}
}
```