zoukankan      html  css  js  c++  java
  • poj2531 Network Saboteur

    Network Saboteur
    Time Limit: 2000MS   Memory Limit: 65536K
    Total Submissions: 11122   Accepted: 5372

    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
    一道poj搜索简单题。

    题意如下:给定一个n*n的方阵描述一个无向带权图,试将改图点集拆分成两个集合使两个集合之间的权值最大。

    思路如下:搜索要解决一下两个问题,第一是如何枚举点兵划分入两个集合,第二是如何剪枝优化。首先,要解决n个点的集合归属,直接暴力枚举,用子集枚举的位向量法即可;而对于第二个问题,这里需要一点逆向思维。求集合之间的权值最大,求的其实是每个集合内部那些不能统计的边权值要最小,这样就可以得到转化,答案=边权和-集合内边权和。所以,进行可行性剪枝:若已枚举了所有点,则记录最小值,回溯;同理,进行最优化剪枝:若当前累计边权大小已超过了历史最小值,就剪枝。

    15781005

      ksq2013 2531 Accepted 664K 313MS G++ 754B 2016-07-22 11:29:51

    代码如下:

    #include<cstdio>
    #include<cstring>
    #include<iostream>
    using namespace std;
    bool sub[21];
    int n,tot,minn=0x3f3f3f3f,w[21][21];
    void dfs(int ind,int sum)
    {
        if(sum>minn)return;
        if(ind>n){
            minn=sum;
            return;
        }
        int tmp=0;
        sub[ind]=0;
        for(int i=1;i<ind;i++)
            if(!sub[i])
                    tmp+=w[ind][i];
        dfs(ind+1,sum+tmp);
        tmp=0;
        sub[ind]=1;
        for(int i=1;i<ind;i++)
            if(sub[i])
                tmp+=w[ind][i];
        dfs(ind+1,sum+tmp);
    }
    int main()
    {
        scanf("%d",&n);
        for(int i=1;i<=n;i++){
            for(int j=1;j<=n;j++){
                scanf("%d",&w[i][j]);
                tot+=w[i][j];
            }
        }
        dfs(1,0);
        printf("%d
    ",tot/2-minn);
        return 0;
    }
    /*
    3
    0 50 30
    50 0 40
    30 40 0
    */
    


  • 相关阅读:
    Tempter of the Bone 搜索---奇偶性剪枝
    uestc 1709 Binary Operations 位运算的灵活运用
    uestc 1072 a ^ b
    uestc Another LCIS
    武汉邀请赛 Key Logger 双向链表
    bnu 29378 Adidas vs Adivon 基础题
    中南月赛F ZZY and his little friends
    日期问题
    开灯问题
    开灯问题
  • 原文地址:https://www.cnblogs.com/keshuqi/p/5957736.html
Copyright © 2011-2022 走看看