搜索和图论_复习
DFS
AcWing 842. 排列数字
代码
#include<bits/stdc++.h> using namespace std; typedef pair<int,int> PII; const int N=10; int path[N]; bool st[N]; int n; void dfs(int x){ if(x>n) return ; for(int i=1;i<=n;i++){ if(st[i]==1) continue; st[i]=1; path[x]=i; dfs(x+1); st[i]=0; } if(x==n){ for(int i=1;i<=n;i++) if(i==n)cout<<path[i]<<endl; else cout<<path[i]<<" "; } } int main(){ cin>>n; dfs(1); return 0; }
843. n-皇后问题
代码
#include <iostream> using namespace std; const int N = 10; int n; bool row[N], col[N], dg[N * 2], udg[N * 2]; char g[N][N]; void dfs(int x, int y, int s) { if (s > n) return; if (y == n) y = 0, x ++ ; if (x == n) { if (s == n) { for (int i = 0; i < n; i ++ ) puts(g[i]); puts(""); } return; } g[x][y] = '.'; //不放皇后 dfs(x, y + 1, s); //放皇后 if (!row[x] && !col[y] && !dg[x + y] && !udg[x - y + n]) { row[x] = col[y] = dg[x + y] = udg[x - y + n] = true; g[x][y] = 'Q'; dfs(x, y + 1, s + 1); g[x][y] = '.'; row[x] = col[y] = dg[x + y] = udg[x - y + n] = false; } } int main() { cin >> n; dfs(0, 0, 0); return 0; }
第二种搜索顺序
#include <iostream> using namespace std; const int N = 20; int n; char g[N][N]; bool col[N], dg[N], udg[N]; void dfs(int u) { if (u == n) { for (int i = 0; i < n; i ++ ) puts(g[i]); puts(""); return; } for (int i = 0; i < n; i ++ ) if (!col[i] && !dg[u + i] && !udg[n - u + i]) { g[u][i] = 'Q'; col[i] = dg[u + i] = udg[n - u + i] = true; dfs(u + 1); col[i] = dg[u + i] = udg[n - u + i] = false; g[u][i] = '.'; } } int main() { cin >> n; for (int i = 0; i < n; i ++ ) for (int j = 0; j < n; j ++ ) g[i][j] = '.'; dfs(0); return 0; }
BFS
bfs一层一层的搜,因此可以找到最短路
844. 走迷宫
#include<bits/stdc++.h> using namespace std; typedef pair<int,int> PII; const int N=111; int n,m; int g[N][N], d[N][N]; int bfs(){ queue<PII> q; q.push({0,0}); memset(d,-1,sizeof d); d[0][0]=0; int dx[]={0,0,1,-1}; int dy[]={1,-1,0,0}; while(q.size()){ PII t=q.front(); q.pop(); 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 && g[x][y] == 0 && d[x][y] == -1) { d[x][y]=d[t.first][t.second]+1; q.push({x, y}); } } } return d[n-1][m-1]; } int main(){ cin>>n>>m; for(int i=0;i<n;i++){ for(int j=0;j<m;j++){ cin>>g[i][j]; } } cout<<bfs()<<endl; return 0; }
链式前向星
int h[N], to[N], pre[M], idx; void add(int a, int b) { to[idx] = b, pre[idx] = h[a], h[a] = idx++; } signed main() { memset(head, -1, sizeof(head)); return 0; }
拓扑排序
过程:
Step0: 预处理得到每个点的入度
Step1: 执行入度为 0 的点(没有前驱),放入一个待执行的容器,在图中删除,
Step2: 删除在图中以他为弧尾的弧删除。
Step3: 重复上面两步,直到所有顶点均输出/途中不存在无前驱的顶点。
此外:
- 如果排序后,还剩下部分点,说明图中有环
- 所有顶点均输出,则图中无环。
848. 有向图的拓扑序列
#include<bits/stdc++.h> #include <cstdio> #include <cstring> #include <iostream> #include <algorithm> using namespace std; typedef pair<int,int> PII; const int N=1e5+10; int n,m; int ru[N]; int top[N]; int cnt=0; int h[N],to[N],pre[N],idx; void add(int a,int b){ to[idx]=b,pre[idx]=h[a],h[a]=idx++; } void topsort(){ queue<int> q; for(int i=1;i<=n;i++){ if(!ru[i]) q.push(i); } while(q.size()){ int t=q.front(); q.pop(); top[cnt++]=t; for(int i=h[t];i!=-1;i=pre[i]){ int j=to[i]; ru[j]--; if(ru[j]==0) q.push(j); } } } int main(){ memset(h,-1,sizeof h); cin>>n>>m; for(int i=0;i<m;i++){ int a,b;cin>>a>>b; ru[b]++; add(a,b); } topsort(); if(cnt==n){ for(int i=0;i<n;i++) cout<<top[i]<<" "; } else puts("-1"); return 0; }
本文作者:kingwzun
本文链接:https://www.cnblogs.com/kingwz/p/17555830.html
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
2022-07-15 二分图 _ 复习
2022-07-15 2016年中国大学生程序设计竞赛 CCPC (杭州)