Network Saboteur
Time Limit: 2000MS | Memory Limit: 65536K | |
Total Submissions: 11694 | Accepted: 5683 |
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).
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 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
題意就是給出一個無向帶權圖, 按頂點將頂點分為2個集合, 求這兩個集合權值差值的最大值。
首先創建一個g[]代表其中的一個集合, 當g[i] == 0 則不在這個集合內, g[i] == 1 則在這個集合里。
void dfs( int site, int sum ); site代表當前拿進去的節點, sum代表前一個狀態的兩個集合的權值的差值。
int num = sum;
這時for一遍g[], 如果是一個集合內則減去這個權值( res -= map[i][site] )若不是一個集合則加上這個權值, 此時更新res的值( res = max( res, num ) )
最后再遍歷剩余的點, 這時候還有一個剪枝:
如果, 如果這個點加入后權值變小了, 則沒有必要加入當前這個點, ( if( num <= sum ) continue; )
不剪枝可能會掛, 但是這道題的測試數據很水~

#include <iostream> #include <cstdio> #include <cstring> #include <algorithm> #define INF 0x3fffffff using namespace std; int res; int map[25][25]; int g[30]; int n; void dfs( int site, int sum ) { g[site] = 1; int num = sum; for( int i = 0; i < n; i++ ) { if( g[i] == 1 ) { num -= map[i][site]; } else { num += map[i][site]; } } res = max( res, num ); for( int i = site + 1; i < n; i++ ) { if( num > sum ) { dfs( i, num ); g[i] = 0; } } return; } int main() { while( cin >> n ) { res = -INF; memset( g, 0, sizeof(g) ); memset( map, 0, sizeof(map) ); for( int i = 0; i < n; i++ ) { for( int j = 0; j < n; j++ ) { cin >> map[i][j]; } } dfs( 0, 0 ); cout << res << endl; } return 0; }
剪枝是很重要的技巧, 另外以后不要光做這種套路題, 要多多做腦洞題, 開大自己的腦洞