P2196 [NOIP1996 提高组] 挖地雷 题解

题目传送门

分析

\(n\le20\),放心 dfs。难点主要在保存路径上。

一个点的地雷只能挖一次,所以需要维护 \(vis\) 数组。

注意,任何点都可以作为起点。

代码

#include <bits/stdc++.h>
using namespace std;

int n;
int a[25];
vector <int> g[25];
vector <int> path;//答案路径
vector <int> cur;//搜索时的临时路径
bool vis[25];
int ans;
bool flag;
void dfs(int x, int sum) {//x 为当前地窖,sum 为已挖到的地雷数
    for (int i = 0; i < g[x].size(); i++) {
        if (!vis[g[x][i]]) {
            vis[g[x][i]] = true;
            cur.push_back(g[x][i]);
            dfs(g[x][i], sum + a[g[x][i]]);
            vis[g[x][i]] = false;
            cur.pop_back();
        }
    }
    //注意更新答案要在回溯之后
    if (sum > ans) {
        ans = sum;
        path.clear();
        path = cur;
        flag = true;
    }
}

int main() {
    cin >> n;
    for (int i = 1; i <= n; i++)cin >> a[i];
    for (int i = 1; i <= n; i++) {
        for (int j = i + 1; j <= n; j++) {
            int b; cin >> b;
            if (b)g[i].push_back(j);//可以到达,连边
        }
    }
    int root = 0;//起点
    for (int i = 1; i <= n; i++) {
        memset(vis, 0, sizeof vis);
        flag = false;
        dfs(i, a[i]);
        if (flag)root = i;//如果更新了答案,更新起点
    }
    cout << root;
    for (auto i = path.begin(); i != path.end(); i++) {
        cout << ' ' << *i;
    }
    cout << endl << ans;
    return 0;
}
posted @ 2022-01-02 16:32  tmjyh09  阅读(79)  评论(0编辑  收藏  举报