요약:
dfs 무차별 대입 검색. 그림의 고정 점 i를 시작점으로 사용하여 검색을 시작하고 dfs를 통해 각 경로를 검색 한 다음 가중치가 가장 큰 경로를 찾습니다.
주제에 대한 간략한 설명 (문제 변환) :
방향성 가중 그래프 인 n 개의 포인트는 인접 행렬을 제공합니다. 무게가 가장 큰 길 찾기
Luogu P1966
알고리즘 분석 :
n 점의 수가 매우 적기 때문에, 따라서 dfs 무차별 대입 검색 방법을 사용할 수 있습니다.
문제 분석은 각 지점에서 특정 수의 광산을 파낼 수 있으며이 조건은 이전 지점과 다음 지점 사이의 가장자리 무게로 변환 될 수 있음을 보여줍니다.
이 질문은 단순한 그래프 이론의 심층 검색과 다릅니다. 그 안의 각 지점은 횟수에 관계없이 순회 될 수 있으므로 순회 된 모든 지점을 액세스 할 수없는 것으로 표시하기 위해 단순히 방문 배열을 사용하는 것은 불가능합니다. 대신 먼저 표시 한 다음 역 추적하는 방법을 사용하여 차단을 해제
하세요 . 자세한 내용은 다음 코드 를 참조하세요.
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; //回溯解封
코드 및 자세한 설명 :
#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;
}