递归实现指数型枚举 dfs vector数组存路径

从 1∼n 这 n 个整数中随机选取任意多个,输出所有可能的选择方案。

输入格式
输入一个整数 n。

输出格式
每行输出一种方案。

同一行内的数必须升序排列,相邻两个数用恰好 1 个空格隔开。

对于没有选任何数的方案,输出空行。

本题有自定义校验器(SPJ),各行(不同方案)之间的顺序任意。

数据范围
1≤n≤15
输入样例:
3
输出样例:

3
2
2 3
1
1 3
1 2
1 2 3

//要么选要么不选dfs
#include<bits/stdc++.h>
using namespace std;
const int N=1e5+10;
int st[N],num[N];
vector<vector<int>>v;
int n;
void dfs(int u){
    if(u==n){
        vector<int>v0;
        for(int i=1;i<=n;i++){
            if(st[i-1]==1){
                v0.push_back(i);
            }
           
            
        }
         v.push_back(v0);
        return;
    }
    st[u]=1;//fang
    dfs(u+1);
    st[u]=2;//bu fang
    dfs(u+1);
    st[u]=0;
}
int main(){
    cin >>  n;
    dfs(0);
    for(int i=0;i<v.size();i++){
        for(int j=0;j<v[i].size();j++){
            cout << v[i][j]<<" ";
        }
        cout << endl;
    }
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
首先,我们需要了解一下深度优先遍历的基本思想:从图的某个顶点开始,沿着深度方向遍历直到不能再继续为止,然后回溯到上一个顶点,再沿着另一个方向继续遍历,直到所有的顶点都被访问过为止。 基于邻接矩阵实现递归的深度优先遍历: ```c++ #include<iostream> #include<stack> using namespace std; const int MAXV = 1000; //最大顶点数 const int INF = 0x3f3f3f3f; //无穷大 int G[MAXV][MAXV]; //邻接矩阵 bool visited[MAXV]; //标记是否已经访问 void DFS(int u) { stack<int> s; s.push(u); //将起点u入栈 visited[u] = true; //标记已经访问 while(!s.empty()) { //栈不为空 int v = s.top(); s.pop(); //弹出栈顶元素 for(int w = 0; w < MAXV; w++) { //枚举所有顶点 if(G[v][w] != INF && !visited[w]) { //如果v到w有边并且w未被访问 s.push(w); //将w入栈 visited[w] = true; //标记已经访问 } } } } int main() { int n, m; //n个顶点,m条边 cin >> n >> m; memset(G, INF, sizeof(G)); //邻接矩阵初始化为INF for(int i = 0; i < m; i++) { int u, v, w; cin >> u >> v >> w; G[u][v] = G[v][u] = w; //无向图 } memset(visited, false, sizeof(visited)); //标记数组初始化为false for(int u = 0; u < n; u++) { if(!visited[u]) { DFS(u); //从未访问过的顶点u开始遍历 } } return 0; } ``` 基于邻接表实现递归的深度优先遍历: ```c++ #include<iostream> #include<stack> #include<vector> using namespace std; const int MAXV = 1000; //最大顶点数 const int INF = 0x3f3f3f3f; //无穷大 struct Edge { //边的结构体 int v, w; //边的另一个顶点v和边权重w Edge(int _v, int _w):v(_v), w(_w) {} //构造函数 }; vector<Edge> adj[MAXV]; //邻接表 bool visited[MAXV]; //标记是否已经访问 void DFS(int u) { stack<int> s; s.push(u); //将起点u入栈 visited[u] = true; //标记已经访问 while(!s.empty()) { //栈不为空 int v = s.top(); s.pop(); //弹出栈顶元素 for(int i = 0; i < adj[v].size(); i++) { //枚举与v相邻的所有顶点 int w = adj[v][i].v; //另一个顶点 if(!visited[w]) { //如果w未被访问 s.push(w); //将w入栈 visited[w] = true; //标记已经访问 } } } } int main() { int n, m; //n个顶点,m条边 cin >> n >> m; for(int i = 0; i < m; i++) { int u, v, w; cin >> u >> v >> w; adj[u].push_back(Edge(v, w)); //加入边(u, v, w) adj[v].push_back(Edge(u, w)); //加入边(v, u, w),因为是无向图 } memset(visited, false, sizeof(visited)); //标记数组初始化为false for(int u = 0; u < n; u++) { if(!visited[u]) { DFS(u); //从未访问过的顶点u开始遍历 } } return 0; } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值