2021-02-26 Luogu P1966 digging landmines-dfs violent search (backtracking method)

Summary:

dfs brute force search. Start the search with any fixed point i in the figure as the starting point, search each path through dfs, and find the one with the largest weight.


Brief description of the topic (problem transformation):

n points, a directed weighted graph, gives the adjacency matrix. Find a path with the greatest weight
Luogu P1966


Analysis of Algorithms:

Since the number of points n is very small, So you can use the dfs brute force search method.
Analysis of the problem shows that at each point, a certain number of mines can be dug, and this condition can be transformed into the weight of the edge between the previous point and the next point.
This question is different from the deep search in simple graph theory. Each point in it can be traversed any number of times, so it is not possible to simply use a visit array to mark all the points that have been traversed as inaccessible. Instead, you should use the method of marking first and then backtracking unblocking.
See the following code for details:

dfs()
	...
	for j in 某点i的邻接点数组//a[i]表示点i的邻接点
		if(visit[i]==true) //证明已经访问过
			continue;
		visit[a[i][j]]=true;  //先标记为已到达过
		path[step+1]=a[i][j]; 
		dfs(a[i][j],当前步数+1,当前的权重+这一步的权重w[a[i][j]])
		visit[a[i][j]]=false; //回溯解封

Code and detailed comments:

#include <iostream>
#include <stdio.h>
#include <vector>
using namespace std;
#pragma warning(disable:4996)


class Solution {
    
    
public:
	int  n, m;
	vector<int> w;
	vector<int> path;
	vector<bool>visit;
	vector<vector<int>> a;
	int ans = 0;
	int count = 0;
	vector<int> res;
	void func() {
    
    
		cin >> n;
		w.resize(n + 1);
		for (int i = 1; i <= n; ++i)
			cin >> w[i];
		a.resize(n+1);
		visit.resize(n + 1, false);
		path.resize(n + 1);
		for(int i=1;i<n;++i)
			for (int j = i + 1; j <= n; ++j)
			{
    
    
				int x;
				cin >> x;
				if(x==1)
					a[i].push_back(j);
			}

		for (int i = 1; i <= n; ++i)
		{
    
    
			path[1] = i;
			visit[i] = true;
			dfs(i, 1, w[i]);
			visit[i] = false;
		}
		for (int i = 1; i <= count; ++i)
			cout << res[i] << " ";
		cout << endl << ans;
	}

	void dfs(int i,int step,int cur) 
	{
    
    
		if (a[i].empty())
		{
    
    
			if (ans < cur )
			{
    
    
				ans = cur;
				res = path;
				count = step;
			}
			return;
		}
		for (int j = 0; j<int(a[i].size()); ++j)
		{
    
    
			if (visit[a[i][j]])continue;
			visit[a[i][j]] = true;
			path[step + 1] = a[i][j];
			dfs(a[i][j], step + 1, cur + w[a[i][j]]);
			visit[a[i][j]] = false;
		}
	}
};
	
int main() {
    
    
	//freopen("in.txt", "r", stdin);
	Solution s;
	s.func();
	return 0;
}

Guess you like

Origin blog.csdn.net/sddxszl/article/details/114111977