Network Saboteur
Time Limit: 2000MS | Memory Limit: 65536K | |
Total Submissions: 15496 | Accepted: 7667 |
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
【题意】
给出n个点,map[i][j]表示第i个点到第j个点的权值,把这些点分为两个部分,使这两部分之间的权值和最大。
【思路】
深搜遍历回溯,一开始定义一个vis[21]数组,全部为0,取出一个cur标记为1,即把这个点放在另一个集合里,对于和cur在一个集合里的点,减去他们之间的权值;不在一个集合里的点,加上他们之间的权值,遍历每一个点,最后的结果为最大值。
AC代码
#include <stdio.h>
#include <string.h>
#include <iostream>
using namespace std;
int dp[21][21];
int vis[21];
int n,ans;
void dfs(int cur,int cost)
{
vis[cur]=1;//取出点
int tmp=cost;
for(int i=0;i<n;++i)
{
if (!vis[i]) //如果不在一个集合,就加上它们之间的权值
tmp+=dp[cur][i];
else //如果在一个集合,减去之间的权值
tmp-=dp[cur][i];
}
if(tmp>ans) //循环结束找到最大值
ans=tmp;
if(tmp>cost) //如果加入了cur以后两个集合之间的权值小了,就不需要搜了
for(int i=cur+1;i<n;++i)//搜剩下的点
{
dfs(i,tmp);
vis[i]=0;
}
}
int main()
{
while(cin>>n)
{
for(int i=0;i<n;++i)
for(int j=0;j<n;++j)
cin>>dp[i][j];
memset(vis,0,sizeof(vis));
ans=0;
dfs(0,0);
cout<<ans<<endl;
}
return 0;
}