POJ-2561 Network Saboteur(DFS)

随声附和 提交于 2020-02-28 10:05:02

题目:

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然后输入n×n的矩阵dis[i][j]代表i到j需要消耗的数值,大致意思是把n个点分成A和B两个集合,求A集合中所有点到B集合中所有点消耗数值的和的最大值。

分析:

dfs从1号结点开始搜索,val记录当前情况消耗的数值。可以用vis数组表示两个集合0/1,当把一个元素从0集合移动到1集合时,这个集合的vis从0变为1,它要加上所有初它自己外它到0集合中元素的数值,它要减去所有初它自己外它到1集合中元素的数值(因为改元素原本在0集合中,val中含有它到1元素数值之和,当它变为1元素后要减去)

代码:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxn = 25;
int dis[maxn][maxn],vis[maxn],ans = 0,n;
void dfs(int u,int val){
    vis[u] = 1;
    int tmp = val;
    for (int i = 1; i <= n; i++){
        if (!vis[i]) tmp += dis[u][i];
        else tmp -= dis[u][i]; 
    }
    ans = max(ans,tmp);
    for (int i = u+1; i <= n; i++){
        dfs(i,tmp),vis[i] = 0;
    }
}
int main(){
    while (~scanf("%d",&n)){
        ans = 0;
        memset(vis,0,sizeof vis);
        for (int i = 1; i <= n; i++){
            for (int j = 1; j <= n; j++){
                scanf("%d",&dis[i][j]);
            }
        }
        dfs(1,0);
        printf("%d\n",ans); 
    }
    return 0;
}
标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!