百度的解释:
深度优先搜索属于图算法的一种,英文缩写为DFS即Depth First Search.其过程简要来说是对每一个可能的分支路径深入到不能再深入为止,而且每个
节点只能访问一次. 举例说明之:下图是一个
无向图,如果我们从A点发起深度优先搜索(以下的访问次序并不是唯一的,第二个点既可以是B也可以是C,D),则我们可能得到如下的一个访问过程:A->B->E(没有路了!
回溯到A)->C->F->H->G->D(没有路,最终
回溯到A,A也没有未访问的相邻
节点,本次搜索结束).
图 简要说明深度优先搜索的特点:每次深度优先搜索的结果必然是图的一个连通分量.深度优先搜索可以从多点发起.如果将每个节点在深度优先搜索过程中的”结束时间”排序(具体做法是创建一个list,然后在每个节点的相邻节点都已被访问的情况下,将该节点加入list结尾,然后逆转整个链表),则我们可以得到所谓的”
拓扑排序“,即topological sort.
[1]
深度优先遍历图的方法是,从图中某顶点v出发: (1)访问顶点v; (2)依次从v的未被访问的邻接点出发,对图进行
深度优先遍历;直至图中和v有路径相通的顶点都被访问; (3)若此时图中尚有顶点未被访问,则从一个未被访问的顶点出发,重新进行
深度优先遍历,直到图中所有顶点均被访问过为止。 当然,当人们刚刚掌握深度优先搜索的时候常常用它来走迷宫.事实上我们还有别的方法,那就是
广度优先搜索(BFS).
思想很简单。
我先就一个问题来讲 经典的0/1背包问题:
数据 :
5 (东西) 10(包得最大重量)
价值 质量
3 2
5 6
6 2
4 5
6 4
/* */
可以用vector<pair<int,int> > v_bag;存储 当然二维数组也可以
先按照质量得大小排序 从小到大。
{(3,2),(6,2),(6,4),(4,5),(5,6)}
讲解的话可以把 其编号 为 a,b,c,d,e;
1: 开始压人数据,a-b-c<10;(重量)测试最大价值为:15
2:压入d时 a-b-c-d>10; 回溯到c的地方 因为没必要 a-b-c-e,因为按照重量的大小安排的
在c位置重新选址也就是d:a-b-d<10 ;价值为:13 所有最大价值不变;继续探索
3.a-b-d-e>10;回溯到d位置。 a-b-e;价值为:14 所以依旧不变;继续探索
重复过程还有继续选首地址 可以的得出结果
代码:
#include <iostream>
#include <stdio.h>
#include <cstring>
#include <string>
#include <vector>
#include <map>
#include <algorithm>
#include <set>
#include <cmath>
#include <math.h>
#include <iomanip>
#include <array>
using namespace std;
int sum_w=0,sum_v=0;vector<int> v_temp,v_temp1;//前者存最大得地址 后者是临时存储得地址
int sum_weight(vector<pair<int,int> > v)//计算总重量
{int sum1=0;
for(int i=0;i<v_temp1.size();++i)
{sum1+=v[v_temp1[i]].second;}
return sum1;}
int sum_value(vector<pair<int,int> > v)//计算总价值
{int sum1=0;for(int i=0;i<v_temp1.size();++i)
{sum1+=v[v_temp1[i]].first;}return sum1;}
void dfs(vector<pair<int,int> > v,int n,int m,int start)//dfs算法
{v_temp1.clear();//清空临时存储得地址;
for(int i=start;i<n;++i)
{ v_temp1.push_back(i);//存入数据
if(sum_value(v)>=sum_v&&sum_weight(v)<=m)//如果临时容器得地址 与最大价值比较;
{ v_temp=v_temp1;//得到最大价值得地址
sum_w=sum_weight(v);
sum_v=sum_value(v);
/* for(int i=0;i<v_temp.size();++i){ cout<<v_temp[i]<<” “<<v_temp[i]<<” “;}cout<<endl;*/
}
if(sum_w>m)//若质量超过了 则回溯到原地方
{v_temp1.pop_back();//删除最后得地址
i=v_temp1[v_temp1.size()-1];//回溯
v_temp1.pop_back();//重先选择新的地址
sum_w=sum_weight(v); sum_v=sum_value(v);
v_temp=v_temp1;
/* for(int i=0;i<v_temp.size();++i) { cout<<v_temp[i]<<” “<<v_temp[i]<<” “; }cout<<endl;*/
} }}
int main(){
vector<pair<int,int> > v_bag;
int n,m,t,t1;
cin>>n>>m;
cin.get();
for(int i=0;i<n;++i)
{ cin>>t>>t1; cin.get(); v_bag.push_back(make_pair(t,t1));}
sort(v_bag.begin(),v_bag.end(),[](const pair<int,int> &x,const pair<int,int> &y)->int{ return x.second>y.second;});
for(int i=0;i<n;++i)//从各个起点开始回溯
{ dfs(v_bag,n,m,i);}cout<<sum_v<<” “<<sum_w<<endl;for(int i=0;i<v_temp.size();++i){ cout<<v_bag[v_temp[i]].first<<” “<<v_bag[v_temp[i]].second<<endl;} return 0;}
如有错误请提示 优化也可以 因为我没优化 哈哈 。。。。。。