DFS 基础

前言

  • DFS= 递归
  • 适于寻找一个最优解
  • 常用技巧: 减枝

判父亲法

void dfs(int u)
{
	//保存父亲
	//标记父亲
	if()//如果父亲是答案就输出(判父亲法) 
	{
		//输出答案 
	} 
	else//如果父亲不是答案,继续从下一代找 
	{
		for(int i=1;i<=N;i++)//枚举第u代的所有孩子的i 
		{
			//生成孩子
			if()//判断孩子的合法性 
			{
				dfs(i);//递归搜索u的孩子 
			} 
		}
	}
	//取消标记 
}

搜索树

vector<int> a[N];
void dfs(int u, int k)
{
    ans[k] = u;
    vis[u] = 1; //标记父亲
    if (u == ans)   //符合
    {
        for (int i = 1; i <= k; i++)
            cout << ans[i] << " ";
        cout << endl;//处理答案
    }
    else
        for (int i = 0; i < a[u].size(); i++)//生成孩子线索
        {
            int v = a[u][i];    //生成孩子
            if (vis[v] == 0)
                dfs(v, k + 1);      //下一个
        }
    vis[u] = 0; //取消标记
}
int main()
{
    for (int i = 1; i <= n; i++)
    {
        int u, v;
        cin >> u >> v;
        a[u].push_back(v);
        a[v].push_back(u);
    }
    dfs(start, 1);
    return 0;
}

判孩子法

void dfs(int k)
{
	for(int i=1;i<=N;i++)//枚举第k代的所有孩子的线索 
	{
		//生成孩子(用i表示出孩子) 
		if()//判孩子的合法性(符合约束条件并且不重复) 
		{
			//保存孩子
			//标记孩子
			if()//如果孩子是答案就输出 
			{
				
			} 
			else//如果孩子不是答案,继续从下一代找 
			{
				dfs(k+1);
			}
			//取消标记 
		}
	}

}

子集树

void dfs(int k)
{
	for(int i=0; i<=1; i++)
	{
		ans[k]=i;
		if(k>=n)
		{
			for(int j=1; j<=k; j++)
				cout<<ans[j]<<" ";
			cout<<endl;
		}
		else
			dfs(k+1);
	}
}

int main()
{
	cin>>n;
	dfs(1);
	return 0;
}

拆分树

void dfs(int s,int k)
{
	for(int i=1; i<=s; i++)
	{
		if(i>=ans[k-1])
		{
			ans[k]=i;
			s-=i;
			if(s==0)
			{
				for(int j=1; j<=k; j++)
					cout<<ans[j]<<" ";
				cout<<endl;
			}
			else
				dfs(s,k+1);
			s+=i;
		}
	}
}

int main()
{
	cin>>n;
	ans[0]=1;
	dfs(n,1);
	return 0;
}

组合树

void dfs(int k)
{
	for(int i=1;i<=n;i++)
	{
		if(i>ans[k-1])
		{
			ans[k]=i;
			if(k>=m)
			{
				for(int j=1;j<=k;j++)
					cout<<ans[j]<<" ";
				cout<<endl;
			} 
			else
				dfs(k+1);

		}
	}
}

int main()
{
	cin>>n>>m;
	dfs(1); 
	return 0;
}

排序树

void dfs(int k)
{
	for(int i=1;i<=n;i++)
	{
		if(vis[i]==0)
		{
			ans[k]=i;
			vis[i]=1;
			if(k>=n)
			{
				for(int j=1;j<=n;j++)
					cout<<ans[j]<<" ";
				cout<<endl;
			} 
			else
				dfs(k+1);
			vis[i]=0;
		}
	}
}

int main()
{
	cin>>n; 
	dfs(1);
	return 0;
}

减枝

  • 1.不合法: 返回
  • 2.花费超过从前查到的最优解: 退出
  • 3.冗余: 退出
  • 4.记忆化
posted @ 2024-11-25 21:39  流氓兔LMT  阅读(1)  评论(0编辑  收藏  举报