题意:在一个网络中有n个节点,现在需要把n个节点分成两部分,每部分之间的通信代价为0,不同部分之间的通信代价为Cij。求一种划分方式,是的总得代价最大。
题解:dfs, 随机化算法都可以。下面给出了两种dfs的实现方法。
方法一:dfs
#include <iostream> using namespace std; int map[22][22], check[22]; int n, ans; void dfs ( int k, int sum ) { if ( k > n ) { ans = sum > ans ? sum : ans; return; } int i, temp; check[k] = 1; temp = 0; for ( i = 1; i < k; i++ ) { if ( check[i] != check[k] ) temp += map[i][k]; } dfs ( k + 1, sum + temp ); check[k] = 0; temp = 0; for ( i = 1; i < k; i++ ) { if ( check[i] != check[k] ) temp += map[i][k]; } dfs ( k + 1, sum + temp ); } int main() { while ( scanf("%d",&n) != EOF ) { memset(check,0,sizeof(check)); for ( int i = 1; i <= n; i++ ) for ( int j = 1; j <= n; j++ ) scanf("%d",&map[i][j]); ans = 0; dfs ( 1, 0 ); printf("%d\n",ans); } return 0; }
#include <iostream> using namespace std; int map[22][22], A[22], B[22]; /* A, B 两部分 */ int n, ans; void dfs ( int k, int sum, int sizeA, int sizeB ) { if ( k > n ) { ans = sum > ans ? sum : ans; return; } int i, temp; A[sizeA+1] = k; temp = 0; for ( i = 1; i <= sizeB; i++ ) temp += map[B[i]][k]; dfs ( k + 1, sum + temp, sizeA + 1, sizeB ); B[sizeB+1] = k; temp = 0; for ( i = 1; i <= sizeA; i++ ) temp += map[A[i]][k]; dfs ( k + 1, sum + temp, sizeA, sizeB + 1 ); } int main() { while ( scanf("%d",&n) != EOF ) { memset(A,0,sizeof(A)); memset(B,0,sizeof(B)); for ( int i = 1; i <= n; i++ ) for ( int j = 1; j <= n; j++ ) scanf("%d",&map[i][j]); ans = 0; A[1] = 1; dfs ( 2, 0, 1, 0 ); printf("%d\n",ans); } return 0; }
#include <ctime> #include <iostream> using namespace std; int map[22][22], group[22]; int main() { int cnt, n, ans, sum, i, j, k; while ( scanf("%d",&n) != EOF ) { for ( i = 1; i <= n; i++ ) for ( j = 1; j <= n; j++ ) scanf("%d",&map[i][j]); cnt = 200000; sum = ans = 0; memset(group,0,sizeof(group)); while ( cnt-- ) { k = rand() % n + 1; group[k] = ! group[k]; for ( i = 1; i <= n; i++ ) { if ( group[i] && group[k] ) sum -= map[i][k]; if ( group[i] && !group[k] ) sum += map[i][k]; if ( !group[i] && group[k] ) sum += map[i][k]; if ( !group[i] && !group[k] ) sum -= map[i][k]; } ans = sum > ans ? sum : ans; } printf("%d\n",ans); } return 0; }