Network Saboteur POJ 2531 回溯搜索

Time Limit: 2000MS   Memory Limit: 65536K
Total Submissions: 12886   Accepted: 6187

Description

A university network is composed of N computers. System administrators gathered information on the traffic between nodes, and carefully divided the network into two subnetworks in order to minimize traffic between parts. 
A disgruntled computer science student Vasya, after being expelled from the university, decided to have his revenge. He hacked into the university network and decided to reassign computers to maximize the traffic between two subnetworks. 
Unfortunately, he found that calculating such worst subdivision is one of those problems he, being a student, failed to solve. So he asks you, a more successful CS student, to help him. 
The traffic data are given in the form of matrix C, where Cij is the amount of data sent between ith and jth nodes (Cij = Cji, Cii = 0). The goal is to divide the network nodes into the two disjointed subsets A and B so as to maximize the sum ∑Cij (i∈A,j∈B).

Input

The first line of input contains a number of nodes N (2 <= N <= 20). The following N lines, containing N space-separated integers each, represent the traffic matrix C (0 <= Cij <= 10000). 
Output file must contain a single integer -- the maximum traffic between the subnetworks. 

Output

Output must contain a single integer -- the maximum traffic between the subnetworks.

Sample Input

3
0 50 30
50 0 40
30 40 0

Sample Output

90

最初的想法是枚举每次选择分组的组员个数,但是后来想到可以统一化处理,所有结点考虑取和不取两种状态,递归求解,
这里注意求值操作要放在递归最后一层判定返回,因为前面的选择对最后结果有影响。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<sstream>
#include<algorithm>
#include<queue>
#include<vector>
#include<cmath>
#include<map>
#include<stack>
#include<set>
#include<fstream>
#include<memory>
#include<list>
#include<string>
using namespace std;
typedef long long LL;
typedef unsigned long long ULL;
#define MAXN  23
#define INF 1000000009
/*
给一个邻接矩阵表示一个图,要求把这个图分为两个部分,让两个部分之间距离和最大
两个部分之间距离和最大,当两个元素属于同一集合的时候两者之间距离为0
*/
int g[MAXN][MAXN], n,ans,k;
bool been[MAXN];

void dfs(int cnt)//当前考虑节点数目
{
    if (cnt == n)
    {
        int sum = 0;
        for (int i = 0; i < n; i++)
        {
            if (been[i])
            {
                for (int j = 0; j < n; j++)
                {
                    if (!been[j])
                        sum += g[i][j];
                }
            }
        }
        ans = max(sum, ans);
        return ;
    }
    been[cnt] = true;
    dfs(cnt + 1);
    been[cnt] = false;
    dfs(cnt + 1);
}

int main()
{
    while (scanf("%d", &n) != EOF)
    {
        ans = -1;
        for (int i = 0; i < n; i++)
            for (int j = 0; j < n; j++)
                scanf("%d", &g[i][j]);    
        dfs(0);
        printf("%d
", ans);
    }
}


原文地址:https://www.cnblogs.com/joeylee97/p/6771304.html