POJ 2531 Network Saboteur

来源:互联网 发布:js九宫格拼图代码 编辑:程序博客网 时间:2024/05/16 15:57
Network Saboteur
Time Limit: 2000MS Memory Limit: 65536K
Total Submissions: 9706 Accepted: 4633
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



这道题刚开始用的动态规划做的。。。。。题意没读懂,以为是从第一台电脑到最后一台电脑最长用多少时间,就拿这道题用“最少经过多少次转换将一个字符串变成回文字符串”的算法来做了。。。。我看到题目中A和B集合没把这个当回事。。活该WA了那么多次。。。。



正规思路:

将1—n个数划分为一个集合,每次从这个集合中拿出一个和剩余集合求最大路径,每次从这个集合中拿出2个和剩余的元素求最大路经,每次从集合中拿出3个元素和剩余元素求最大路经。。一直到n个元素全都拿到令一个集合中。提交,超时。

然后想了想,把1拿到一个集合中,计算1和其他元素的路径之和,再把1和2拿到一个集合中,计算1,2和其他元素(也就是另一个集合)的路径之和,,在把2放回原来的集合中,把3拿到对方集合中,这时候1和3就在同一个集合中,这时候计算1,3和另一个集合的所有元素的路径之和。以此类推,两个元素在一个集合的情况执行完了之后,在执行3个元素的,最后执行n个元素的。优化时间的关键在每一次将集合添加新数的时候,都有1,因为这就是优划,下面打个比方:

把所有情况都列出来:(假设拿测试案例来说)

第一种情况:{1}和{2,3}

                         {1,2}和{3}

                          {1,3}和{2}

第二种情况:{2}和{1,3}

                          {2,1}和{3}

                         {2,3}和{1}

第三种情况:{3}和{1,2}

                           {3,1}和{2}

                         {3,2}和{1}

仔细看看这三种情况,是不是一样的?所以就按照第一种情况来计算就好了。用到了集合,深搜,和回溯。



#include <iostream>#include <cstring>#include <cstdio>#include <set>using namespace std;int sum;set<int>p;int n;int ans;int a[50][50];void dfs(int id){  //  p.insert(id);    for(int i=1;i<=n;i++)    {        if(p.count(i))            sum-=a[id][i];        else            sum+=a[id][i];    }    int d=sum;    ans=(ans>sum)?ans:sum;    for(int i=id+1;i<=n;i++)    {        if(p.count(i)==0&&id+1!=n)        {            p.insert(i);            dfs(i);            p.erase(i);            sum=d;        }    }  //  p.erase(id);}int main(void){   // freopen("A.txt","r",stdin);   // int n;    scanf("%d",&n);    for(int i=1;i<=n;i++)        for(int j=1;j<=n;j++)    scanf("%d",&a[i][j]);   /* for(int i=1;i<=n;i++)    {         for(int j=1;j<=n;j++)        printf("%d",a[i][j]);        printf("\n");    }*/    ans=0;        sum=0;        p.insert(1);        dfs(1);    printf("%d\n",ans);    return 0;}

0 0
原创粉丝点击