ACM_程序设计竞赛:穷举法:DFS(深度优先)
来源:互联网 发布:sql 数据库 培训 编辑:程序博客网 时间:2024/06/05 11:29
DFS的伪码
- 从顶点v出发;
- 访问v相邻且未被访问的顶点
w1 - 依次
w2,...., ,直到不能继续 - 退回到出发点v,
- 若v的领域还有为访问结点,重复上述
//结果:abdceghf
bool visited[MAX_VERTEX_NUM]; //访问数组标记void DFSTraverse(Graph G){ //对图G深度遍历,访问函数是visit() for(v=0; v<G.vexnum;++v) visited[v]=FALSE; // 初始化访问标记 for(v=0;v<G,vexnum;++v) //从v=0开始遍历 if(!visited[v]) DFS(G,v);}void DFS(Graph G, int v){ //从顶点v出发,采用递归,深度遍历 visit(v); // 访问顶点v visited[v]=TRUE; //标记访问 for(w=FirstNeighbor(G,v); w>=0;w=NextNeighor(G,v,w)) //FirstNeighbor()=图G中顶点x的第一个领接点,有则返回序列号 //NextNeighor()=如果y是x的一个领接点,返回除y之外的顶点x的下一个领接点号 if(!visited[w]) DFS(G,w); }
- 复杂度
- 借助栈工作:空间复杂度:O(|V|)
- 领接矩阵:查找每个顶点的时间复杂度是
O(|v|2) - 领接表:查找的时间(O(|E|)),访问的时间O(|v|); 总时间=O(|V|+|E|)
部分和问题
给定整数:
a1,a2,...,an , 判断是否可以从中选出若干数,是其和恰好是k
*限制条件1<=n<=20 −108<=ai<=108 −108<=k<=108 例子
输入:
n=4
a={1,2,4,7}
k=13
输出:
YES {13=2+4+7}例子
输入:
n=4
a={1,2,4,7}
k=15
输出:
NO
- 伪代码
// 输入:int a[MAX_N];int n; //数组个数 int k; //部分和//前i项得到了和sum,现在对i项之后分支计算dfs(项数i,部分和sum)1.0 如果,i==n ; 判断是否sum==k;2.0 不加a[i];2.1 如果,dfs(i+1,sum)成立,返回,true;3.0 加上a[i]3.1 如果dfs(i+1,sum+a[i])成立,返回,true4.0 都不成立返回,falsesolve()1.0 if(dfs(0,0)), true,打印2.0 if(dfs(0,0)),false,打印
#include <iostream>using namespace std;bool dfs (int i, int sum, int* a, int n, int k) { if (i==n) return sum == k; if(dfs(i+1, sum, a, n, k)) return true; if(dfs(i+1, sum+a[i], a, n, k)) return true; return false;}void solve(int* a, int n, int k) { if (dfs(0,0,a,n,k)) cout<<"Yes"<<'\n'; else cout <<"No"<<'\n';);}int main(void){ const int MAX_N = 20; int a[MAX_N] = {1, 2, 4, 7}; int n = 4, k = 13; //k位需要找到的数字 solve(a, n, k); return 0;}
- 赋值度
O(2n)
lake counting
- 题目
大小为 N*M 的园子,雨后积水,八连通的积水被认为是联系在一起的,求园子有多少水洼
//八连通****w****//输入:N=10,M=12;(w表示积水,*表示没有水)w*********ww**www******www****ww***ww**********ww**********w****w******w***w*w*****ww*w*w*w*****w**w*w******w***w*******w*//输出:3
算法:
- 从任意w开始,将领接部分用”*”替换
- 1次DFS后,与初始
w 连接的所有w都被替换为∗ - 知道图中没有w
- 总共进行的DFS次数就是水洼数
复杂度:O(8*N*M)
#include <iostream>using namespace std;const int MAX_N = 10;const int MAX_M = 12;char field[MAX_N][MAX_M+1] = {"+********++*","*+++*****+++","****++***++*","*********++*","*********+**","**+******+**","*+*+*****++*","+*+*+*****+*","*+*+******+*","**+*******+*"};//现在位置(x,y)void dfs(int x, int y){ field[x][y]='.'; //循环遍历移动的8个方向 for(int dx=-1;dx<=1;dx++){ for(int dy=-1;dy<=1;dy++){ //x方向移动dx,y方向移动dy,移动结果(nx,ny) int nx=x+dx,ny=y+dy; //判断(nx,ny)是不是园子内及是否有积水 if(0<=nx && nx<MAX_N && 0<=ny && ny<MAX_M && field[nx][ny]=='+') dfs(nx,ny); } } return ;}void solve(){ int res=0; for(int i=0;i<MAX_N;i++){ for(int j=0;j<MAX_M;j++){ if(field[i][j]=='+'){ dfs(i,j); res++; } } } cout<<res<<'\n'<<endl;}int main(int argc, char* argv[]){ solve(); return 0;}
0 0
- ACM_程序设计竞赛:穷举法:DFS(深度优先)
- ACM_程序设计竞赛:穷举法:BFS(广度优先)
- 挑战程序设计竞赛:深度优先搜索
- ACM_程序设计竞赛:贪心算法:硬币问题
- ACM_程序设计竞赛:贪心算法:区间问题
- ACM_程序设计竞赛:贪心算法:saruman army
- ACM_程序设计竞赛:DP:01背包
- ACM_总论_国际大学生程序设计竞赛考点
- ACM_程序设计竞赛:贪心算法:字典最小序
- 深度优先搜索 DFS
- 深度优先搜索 DFS
- 深度优先遍历DFS
- DFS 深度优先搜索
- 深度优先(DFS)
- dfs深度优先算法
- DFS 深度优先搜索
- 深度优先搜索(DFS)
- DFS-深度优先遍历
- 防止头文件重复包含之pragma once与#ifndef
- javascript的方法可以分为三类:
- 05-百思不得姐(第五天)
- Codeforces E. Bear and Contribution(枚举维护)
- Fluent Nhibernate and Stored Procedures
- ACM_程序设计竞赛:穷举法:DFS(深度优先)
- 静态方法与非静态方法的区别
- Fluent Nhibernate and Stored Procedures
- POJ 3190(Stall Reservations 区间贪心)
- iOS判断字符串中包含数字和字母的几种情况
- Spring AOP注解通过@Autowired,@Resource,@Qualifier,@PostConstruct,@PreDestroy注入属性的配置文件详解
- myHomework Student Planner(学习规划)
- 什么是代码混淆?andriod和android-studio工程如何启用代码混淆功能?
- m_pImageBuffer转换到opencv的一种笨方法