Network Saboteur
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 Source
Northeastern Europe 2002, Far-Eastern Subregion
|
提示
题意:
给你n(2<=n<=20)个点,把这些点分为两部分,使得∑Cij最大。(只有i,j在不同的集合Cij才会有值)
思路:
DFS去枚举吧。
示例程序
Source Code
Problem: 2531 Code Length: 725B
Memory: 392K Time: 47MS
Language: GCC Result: Accepted
#include <stdio.h>
#include <string.h>
int v[20],map[20][20],max=0;
void dfs(int pos,int sum,int n)
{
int i,t=sum; //sum取出来进行运算,看看会不会有所增加
for(i=0;n>i;i++)
{
if(v[i]==0)
{
t=t+map[pos][i]; //对放入1集合中与0集合新产生的Cij加进去
}
else
{
t=t-map[pos][i]; //同样会损失pos点在之前与1集合所产生的Cij
}
}
if(t>max) //进行比较
{
max=t;
}
for(i=pos+1;n>i;i++) //从pos+1开始,因为之前的点已经确定了位置
{
if(t>sum) //当前方式比上一次的sum大,我们进行搜索(实际上可以放到for外)
{
v[i]=1; //把点放入1集合中
dfs(i,t,n);
v[i]=0; //放回0集合中
}
}
}
int main()
{
int n,i,i1;
scanf("%d",&n);
for(i=0;n>i;i++)
{
for(i1=0;n>i1;i1++)
{
scanf("%d",&map[i][i1]);
}
}
memset(v,0,sizeof(v));
v[0]=1; //这里从0点开始放入1集合中
dfs(0,0,n);
printf("%d",max);
return 0;
}