图的遍历和应用
- 实现方式:邻接矩阵可以使用vector。邻接矩阵的无穷表示方法:
memset( road, 0x3f, sizeof(road) );
- 应用场景:拓扑图、最小生成树、最短路径、二分图、DFS、BFS。
全排列问题
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
| const int N = 7; int path[N+1]; bool vset[N+1]; int n;
void dfs(int x) { if(x == n) { for(int i = 0; i < n; i++) cout << path[i]; cout << endl; } else { for(int i = 1; i <= n; i++ ) { if (vset[i] == false) { path[x] = i; vset[i] = true; dfs(x+1); vset[i] = false; } } } }
int main() { scanf("%d", &n); memset(vset, false, sizeof vset); dfs(0); }
|
n皇后
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
| const int N = 10; char path[N+1][N+1]; bool col[N], zp[2*N], xp[2*N]; int n;
void dfs(int x) { if(x == n) { for(int i = 0; i < n; i++) puts(path[i]); puts(""); } else { for(int i = 0; i < n; i++) { if (!col[i] && !zp[x + i] && !xp[n - x + i ]) { path[x][i] = 'Q'; col[i] = zp[x + i] = xp[n - x + i ] = true; dfs(x+1); path[x][i] = '.'; col[i] = zp[x + i] = xp[n - x + i ] = false; } } } }
int main() { scanf("%d", &n); for(int i = 0; i < n; i++) { for (int j = 0; j < n; j++){ path[i][j] = '.'; } } dfs(0); }
|
迷宫问题
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34
| const int N = 100, M = 100; int path[N][M], vset[N][M]; int n, m; typedef pair<int, int> PII; PII q[N * N];
void bfs() { int front = 0, rear = 0; q[0] = {0, 0}; int dx[4] = {-1, 0, 1, 0}, dy[4] = {0, 1, 0, -1}; while(front<=rear) { auto t = q[front++]; for(int i = 0; i < 4; i++) { int x = t.first + dx[i], y = t.second + dy[i]; if(x>=0 && x<n && y>=0 && y< m && vset[x][y] == -1 && path[x][y] == 0) { vset[x][y] = vset[t.first][t.second] + 1; q[++rear] = {x, y}; } } } }
int main() { scanf("%d%d", &n, &m); for(int i = 0; i < n; i++) { for (int j = 0; j < m; j++){ scanf("%d", &path[i][j]); vset[i][j] = -1; } } vset[0][0] = 0; bfs(); printf("%d", vset[n-1][m-1]); }
|
有向图的拓扑排序 O(n+e)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46
|
int x, y, n; queue<int> q; vector<int> v; vector<int> findOrder(int numCourses, vector<vector<int>>& prerequisites) { vector<int> G[numCourses]; n = prerequisites.size(); cout << n << " "; int indegree[numCourses]; for(int i = 0; i < numCourses; i++) { indegree[i] = 0; } for(int i = 0; i < n; i ++) { x = prerequisites[i][0]; y = prerequisites[i][1]; indegree[x]++; G[y].push_back(x); } for(int i = 0; i < numCourses; i++) { cout << indegree[i] << " "; } for(int i = 0; i < numCourses; i++) { if(indegree[i]==0) { q.push(i); } } while(!q.empty()) { int p = q.front(); q.pop(); v.push_back(p); for(int j = 0; j < G[p].size(); j++) { int k = G[p][j]; --indegree[k]; if(indegree[k]==0) q.push(k); } } if(v.size() == numCourses) return v; else { v.clear(); return v; } }
|
染色法判断二分图
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
| bool check(AGragh *g) { int n = g.n; int color[maxsize]; for(int i = 0; i < g.n; i++ ) { color[i] = -1; } int flag = true; for(int i = 0; i < n; i++) { if(color[i] == -1) { if(!dfs(i, 0)) { flag = false; break; } } } return flag; }
bool dfs(int x, int c) { color[x] = c; AcrNode *p = g->adjList[x].firstarc; while(p){ int k = p->adjvex; if(!color[k]) { if(!dfs(k,!c)) return false; p = p->nextarc; } else if(color[k] == c) return false; } return ture; }
|
匈牙利算法 —— 最大匹配
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
| int match[n]; bool st[n]; int main(AGragh *g) { int n = g.n; int res = 0; memset(st, false, sizeof st); memset(match, 0, sizeof match); for(int i = 0; i < n; i++) { if(find(i)) res++; } }
bool find(int x) { ArcNode *p = g->adjList[x].firstArc; while(p) { int j = p->adjvex; if(!st[j]){ st[j] = true; if(match[j] == 0 || find(match[j])) { match[j] = x; return true; } p = p->nextarc; } } return false; }
|
代码与知识点均学习自AcWing:https://www.acwing.com/activity/