POJ 2531 Network Saboteur

23 篇文章 0 订阅
17 篇文章 0 订阅
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
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值