poj2513Network Saboteur(dfs+简单减枝)

Network Saboteur
Time Limit: 2000MS Memory Limit: 65536K
Total Submissions: 11199 Accepted: 5411

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
#include<stdio.h>
int map[25][25];
int vis[25];
int n;
int ans;
void dfs(int id,int data)
{
   vis[id]=1;//将id从0的集合里放到1的集合里面
   int sum=data;

   for(int i=1;i<=n;i++)
   {
       if(!vis[i])
        sum+=map[i][id];//如果两者不是同一个集合的就相加
       else
        sum-=map[i][id];//如果两者在同一个集合就消除以前不在同一个集合时相加的边

   }
   if(ans<sum)//更新最大值
      ans=sum;

      for(int i=id+1;i<=n;i++)
      {
          if(sum>data)//简单的减枝,如果id的值放在这个集合里面已经使 这些权值的和减少,如果在从0里面拿边添加岂不是更小,所以sum值必须
                      //比data大,依次为减枝条件
          {
              dfs(i,sum);
              vis[i]=0;//回溯
          }
      }


}
int main()
{
    int i,j;
    while(~scanf("%d",&n))
    {
        for(i=1;i<=n;i++)
        {
            for(j=1;j<=n;j++)
            scanf("%d",&map[i][j]);
        }
        ans=-1;
        dfs(1,0);
        printf("%d\n",ans);
    }
return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值