POJ 2531 Network Saboteur

来源:互联网 发布:c语言算法是什么 编辑:程序博客网 时间:2024/06/09 21:11

题目:

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

30 50 3050 0 4030 40 0

Sample Output

90

这个题目,我从头到尾都感觉像是动态规划。

虽然没有用数组记录(我觉得这是我的时间非常长,接近2秒,快超时了,的重要原因),但是在函数递归调用的过程中,还是避免了一些重复计算的,不过也产生了一些不必要的计算,我没有想到这样居然反而特别慢。

为了实现这种思想,我用了二进制和划分的对应,比如100000对应划分{{a}{bcdef}},010111对应划分{{bdef}{ac}},等等。

应该就是因为有这种附加运算,才会导致运行时间比较长。

还有一个因素,我是把所有的情况都精确求出来了,中途没有估值剪枝什么的。

最开始的时候我的思路是不用二维数组记录,只用2个一维数组,边输入数据边记录输入矩阵的上三角部分的行和和列和,

我以为结果是可以用这些行和和列和表示的,后来写完一运行才发现算的不对。

代码:

#include<iostream>using namespace std;int maxx;int place(int n, int **list, int nn){if (n == 0)return 0;if (n == 1){int result = 0;for (int i = 0; i < n; i++)result += list[0][i];return result;}int d = 0, m = n;while (m){d++;m /= 2;}m = 1;for (int i = 0; i < d - 1; i++)m *= 2;int r = place(n - m, list, nn);for (int i = 0; i < nn; i++){if (n % 2)r -= list[i][d - 1];else r += list[i][d - 1];n /= 2;}if (maxx < r)maxx = r;return r;}int main(){int n;while (cin >> n){int **list = new int*[n];for (int i = 0; i < n; i++){list[i] = new int[n];for (int j = 0; j < n; j++)cin >> list[i][j];}maxx = 0;int m = 1;for (int i = 0; i < n-1; i++)m *= 2;for (int i = m; i < m * 2; i++)place(i, list, n);cout << maxx << endl;}return 0;}

之所以用maxx而不是max是因为OJ里面的编译器不一样,它会提示命名冲突。


2 0
原创粉丝点击