题目描述:
http://poj.org/problem?id=2531
中文大意:
一个网络由 N 台计算机组成,各计算机节点之间交流信息都会消耗流量。
为了最大程度地减少各节点之间的流量消耗,可以将节点划分为两个子集,即将网络分为两个子网。
同一个子集中的计算机节点,相互之间交流信息不消耗流量,不同子集间的计算机节点相互交流会消耗流量。
现在有一个坏蛋,他决定重新分配计算机,以最大程度地提高两个子网之间的流量消耗。
各节点之间的流量消耗以矩阵 C 的形式给出,其中 Cij 表示第 i 个节点与第 j 个节点之间的流量消耗。
思路:
从节点 0 开始,逐个划分所有节点。
每个节点都有两种可能:①被划分到集合一,②被划分到集合二。
选择一种可能进行深入,直至划分了所有节点。
回溯回来后尝试另一种可能。
代码:
#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;
int n;
int cost[20][20];//用户输入信息
bool visited[20] = {false};//visited[i] = true 表示节点 i 划分到了集合一
int max_sum;//最大流量
void dfs(int row){
//划分完毕
if(row == n){
//计算不同子集间的计算机节点消耗流量
int sum = 0;
for(int i=0;i<n;i++){
//当前节点属于集合一
if(visited[i]){
//遍历集合二中的节点
for(int j=0;j<n;j++){
if(!visited[j]){
sum += cost[i][j];
}
}
}
}
//寻找流量消耗最大的方案
max_sum = max(sum, max_sum);
return;
}
//将节点 row 划分到集合一
visited[row] = true;
//处理下一个节点
dfs(row+1);
//将节点 row 划分到集合二
visited[row] = false;
dfs(row+1);
}
int main(){
scanf("%d", &n);
for(int i=0;i<n;i++){
for(int j=0;j<n;j++){
scanf("%d", &cost[i][j]);
}
}
max_sum = -1;
dfs(0);
printf("%d
", max_sum);
}