赞
踩
#include<bits/stdc++.h> #define x first #define y second using namespace std; typedef long long ll; typedef pair<int,int> PII; // 解题思路: const int N=1e5+5; vector<int> e[N]; // 存储每个节点可达节点的编号 // u:当前节点,fa:父节点,存储父节点是为了避免往回走 void dfs(int u,int fa) { cout<<u<<' '; // 输出当前点的编号,dfs遍历顺序 // 对于节点u的所有儿子节点 for(auto v:e[u]) { if(v==fa) continue; // 避免往回走,因为是有向边 dfs(v,u); // 往下走 } } int n,m; // 节点数和边数 int a,b; // 起点和终点 /* 8 7 3 6 8 6 2 5 5 6 1 5 5 7 1 4 */ int main() { cin>>n>>m; for(int i=1;i<=m;i++) { cin>>a>>b; // 双向边 e[a].push_back(b); e[b].push_back(a); } dfs(1,0); // 从根节点1开始走,默认0是至高节点 return 0; }
// 多叉树
void dfs2(int u, int fa) {
printf("入%d\n", u);
// 下和回有多次
for (auto v : e[u]) {
if (v == fa) continue;
printf("下%d->%d\n", u, v); // 下
dfs2(v, u);
printf("回%d<-%d\n", u, v); // 回
}
printf("离%d\n", u);
}
// 二叉树
void dfs3(int u) {
printf("先%d\n",u);
dfs3(2*u); // 访问左孩子
printf("中%d\n",u);
dfs3(2*u+1); // 访问右孩子
printf("后%d\n",u);
}
int ne[N]; // 每个节点的下一个节点编号(类似链表)
// 一条链
void dfs4(int u) {
printf("入%d\n",u);
dfs4(ne[u]); // 下一个相连的节点编号
printf("离%d\n",u);
}
#include<bits/stdc++.h> #define x first #define y second using namespace std; typedef long long ll; typedef pair<int,int> PII; // 解题思路: const int N=1e5+5; int n,m,a,b; int vis[N]; vector<int> e[N]; void dfs(int u) { // 入 vis[u]=true; // 当前节点被访问过 for(auto v:e[u]) { // 下 if(vis[v]) continue; // 如果遍历过了就跳过 printf("%d→%d\n",u,v); dfs(v); // 回 } // 离 } int main() { cin>>n>>m; for(int i=1;i<=m;i++) { cin>>a>>b; e[a].push_back(b); e[b].push_back(a); } dfs(1); return 0; }
#include<bits/stdc++.h> #define x first #define y second using namespace std; typedef long long ll; typedef pair<int,int> PII; // 解题思路: const int N=5+2; // 偏移量 const int dx[]={0,1,-1,0,0}; const int dy[]={0,0,0,1,-1}; int n,m,t; // 地图行数列数,障碍数 int sx,sy,fx,fy,x,y; // 起点和终点坐标以及障碍坐标 int g[N][N]; // 地图最大为5×5,O(2^25)实际会小很多 int ans; // 当前所在位置(x,y) void dfs(int x,int y) { // 1)边界条件 if(x==fx && y==fy) { ans++; return; } // 2)试探 for(int i=1;i<=4;i++) { int xx=x+dx[i]; int yy=y+dy[i]; // 3)约束条件 if(xx<1 || yy<1 || xx>n || yy>m) continue; // 越界处理 if(g[xx][yy]==1) continue; // 有障碍或者访问过了 // 能走,占据方案,递归到下一层 g[xx][yy]=1; dfs(xx,yy); g[xx][yy]=0; // 4)回溯,找所有方案 } } int main() { cin>>n>>m>>t; cin>>sx>>sy>>fx>>fy; while(t--) { cin>>x>>y; g[x][y]=1; // 回溯时不会去掉标记 } // 起点打标记 g[sx][sy]=1; // 提前打上的标记回溯时不会去掉,只有dfs中的会去掉 dfs(sx,sy); cout<<ans<<endl; return 0; }
#include<bits/stdc++.h> #define x first #define y second using namespace std; typedef long long ll; typedef pair<int,int> PII; // 解题思路: 马走日,原本8个方向,但是只能往右走,所以dy必须>0 const int N=18+5; const int dx[]={0,1,2,-1,-2}; const int dy[]={0,2,1,2,1}; int n,m; // 终点 bool st[N][N]; int cnt; void dfs(int x,int y) { // 1)边界条件,到达终点 if(x==n && y==m) { cnt++; return; } // 2)试探 for(int i=1;i<=4;i++) { int xx=x+dx[i]; int yy=y+dy[i]; // 3)约束条件 // 越界处理 if(xx<0 || yy<0 || xx>n || yy>m) continue; // 注意本题限制了方向只能往右走,所以不存在往回走的情况 // 不需要状态数组 dfs(xx,yy); } } int main() { cin>>n>>m; // 注意右上角是(m,n),即行是n,列是m dfs(0,0); cout<<cnt<<endl; return 0; }
题目链接:P1219 USACO1.5 八皇后 Checker Challenge - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)
#include<bits/stdc++.h> #define x first #define y second using namespace std; typedef long long ll; typedef pair<int,int> PII; // 解题思路: const int N=13+5; // 棋盘最大范围 int n; // 棋盘大小 int x[N]; // x[i]:第i个皇后(第i行上的皇后)所在的列数 //int g[N][N]; // 地图,不需要地图嗷 int cnt; // 看第u个皇后是否能放,与前u-1个皇后作比较 bool place(int u) { for(int i=1;i<=u-1;i++) { // 剪枝函数,若不在同一列或同一对角线 if(x[u]==x[i] || abs(u-i)==abs(x[u]-x[i])) { return false; // 不能放 } } return true; // 能放 } int idx; // 当前在放第u个皇后 void dfs(int u) { // 1)边界条件 if(u>n) { // 皇后放完了,找到可行解了,直接输出 // 只输出前3个 if(++idx<=3) { for(int i=1;i<=n;i++) { cout<<x[i]<<' '; } cout<<endl; } cnt++; return; } // 2)试探,遍历所有可放的列 for(int i=1;i<=n;i++) { // 3)如果能和前u-1行的皇后不冲突,则占据,向下递归 x[u]=i; if(place(u)) dfs(u+1); x[u]=0; // 4)释放,状态复原 } } int main() { cin>>n; dfs(1); // 从第一个皇后开始放 cout<<cnt<<endl; return 0; }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。