poj2531(深搜剪枝)


題意就是把節點分成A、B兩組,節點間距C給了,要求解分組的方法,使得∑Cij (i∈A,j∈B)最大。

首先把所有節點都放在一組,然后采用深度優先搜索的方法,對每一個節點都做判斷是否應該移到另一組去,判斷的依據是移過去和不移過去哪個得到的和值比較大(這里移去B組后的計算方法就是加上該點和在A組中的所有點的間距,和減去原本就在B組中的所有點的間距),如果移過去變小了,那么則不移過去,並剪掉該條支路。

DFS的本質就是枚舉,一種遞歸的枚舉。比如如果這個程序里面不剪枝的話就可以枚舉到所有的分組情況。剪枝是優化的方法,對滿足一定條件的做出判斷,認為枚舉下去已經沒有意義,所以剪掉其分支。

#include <iostream>
using namespace std;

const int MAX_N = 20;
int n;
int map[MAX_N + 1][MAX_N + 1];
bool in_group[MAX_N + 1];
int ans;

void dfs(int id, int cur_sum)
{
    in_group[id] = true;
    int tmp_sum = cur_sum;
    for (int i = 1; i <= n; i++){
        if (in_group[i]){
            tmp_sum -= map[id][i];
        }
        else{
            tmp_sum += map[id][i];
        }
    }
    if (tmp_sum > ans){
        ans = tmp_sum;
    }
    if (tmp_sum > cur_sum){
        for (int i = id + 1; i <= n; i++){
            dfs(i, tmp_sum);
        }
    }
    in_group[id] = false;
}


int main()
{
    cin >> n;
    memset(in_group, 0, sizeof(in_group));
    ans = 0;
    for (int i = 1; i <= n; i++){
        for (int j = 1; j <= n; j++){
            cin >> map[i][j];
        }
    }
    dfs(1, 0);
    cout << ans << endl;
    return 0;
}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM