ACM_程序设计竞赛:穷举法:DFS(深度优先)
2016-03-30 01:11
465 查看
DFS的伪码
从顶点v出发;访问v相邻且未被访问的顶点w1w_1
依次w2,....,w_2,....,,直到不能继续
退回到出发点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(|v|^2)
领接表:查找的时间(O(|E|)),访问的时间O(|v|); 总时间=O(|V|+|E|)
部分和问题
给定整数:a1,a2,...,ana_1,a_2,...,a_n, 判断是否可以从中选出若干数,是其和恰好是k*限制条件
1<=n<=201 <= n <=20
−108<=ai<=108-10^8 <=a_i <=10^8
−108<=k<=108-10 ^8 <=k <= 10^8
例子
输入:
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])成立,返回,true 4.0 都不成立返回,false solve() 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)O(2^n)
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后,与初始ww连接的所有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; }
相关文章推荐
- Win7下Python2.7环境安装paramiko模块
- NetLoader的二次封装——返回实体类
- 设计模式,行为方法模式(迭代器模式)
- Linux环境下配置java环境
- Python Paramiko模块安装和使用
- hibernate5(2)初入门配置实例
- ISBN号码
- 生成唯一性流水号
- The Top 500 Worst Passwords of All Time
- 软件测试homework3
- 我们真的需要那么多专项吗?
- 实验:C++实验2-【项目1】标准体重
- Web Service实例
- QT8&9&10 Login Form using sqlite in QT application
- hibernate5(1)新特性展示
- java实现:根据图片生成配色方案
- RunLoop原理与核心机制
- Android学习之WebView使用总结
- BZOJ2965 : 保护古迹
- 了解RxJava之操作符(二)