把一个完全图分成两部分

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

//Memory Time
//188K 375MS

#include<iostream>
using namespace std;

const int TimeLimit=2000; //本题时间限制为2000ms

int main(int i,int j)
{
int n;
while(cin>>n)
{
/*Input*/

int w[30][30]={0};
for(i=1;i<=n;i++)
for(j=1;j<=n;j++)
{
cin>>w[i][j];
w[j][i]=w[i][j]; //双向完全图
}

/*Random Algorithm*/

bool subset[30]={false}; //A集:true B集:false
int time=TimeLimit*100; //使随机次数尽可能大,随机结果尽可能接近最优解
long max_w=0; //最大割的权值之和
long sum=0; //当前边割集权和

while(time--)
{
int x=rand()%n+1; //生成随机数 x,对应于总集合的某个结点x
//注意由于使用的结点序号为1~n,对应了数组下标,下标为0的数组元素没有使用
//那么这里必须+1,因为若rand()=n,那么再对n取模结果就为0
//这时就会导致使用了不存在的 [0]结点,本应使用的 [n]结点就被丢弃了

subset[x]=!subset[x]; //改变x所在的集合位置

for(int i=1;i<=n;i++) //由于是完全图,所以每个顶点i都与x相关联,因此要全部枚举
{
if(subset[i]!=subset[x]) //结点i 和 x分别在两个集合内
sum+=w[i][x]; //就是说因为x所在集合的改变,使得割边的个数增加
//割集的原权值 要加上 当前新加入的割边(i,x)的权值

if(i!=x && subset[i]==subset[x]) //结点i 和 x分别在相同的集合内,但他们不是同一元素
sum-=w[i][x]; //就是说因为x所在集合的改变,使得割边的个数减少
//割集的原权值 要减去 当前失去的割边(i,x)的权值
}

if(max_w < sum)
max_w = sum;
}

cout<<max_w<<endl;
}
return 0;
}

把一个完全图分成两部分

时间: 2024-08-05 15:15:12

把一个完全图分成两部分的相关文章

sqlserver 一个字段分成两个字段 截取,保存

Ma,LeiTo(Ma,lT) 分割后为 姓       名 Ma,LeiTo  Ma,lT SELECT LEFT(作者, CHARINDEX('(', 作者) - 1) AS 姓 , replace( STUFF(作者,1, CHARINDEX('(', 作者) , ''),')','') AS 名 ,* FROM 作者表

[官方说明] 为什么ES4要分成两阶段?

从ES4第一个版本发布到现在,已经有段时间了,绝大多数坛友都已经适应了ES4所带来的新封装模式,但仍有部分新人和坛友对ES4的两阶段模式带有不解或曲解.本帖将就ES4的两阶段意义做出解释说明,希望更多朋友能体会ES4两阶段模式的设计目的. 1.什么是封装 讨论问题之前,我们先来简单说说什么是封装. 其实“封装”这个词翻译的太过抽象了,而原词汇“Sysprep”却是一个很具象化的词语,原意是“将系统(sys)准备好(prep)”,换句话说,就是将系统设定为可以部署(deploy)的状态. 封装本身

一个数组构造两个堆栈

***用一个数组表示两个堆栈,最大限度的利用空间 0 1 2 3 若果像右图中从中间分成两部分,则可能存在其中一个堆栈满了,而另一个堆栈还有空的,为你最大限度的利用空间,需要两边像中间长,知道指针碰头表示堆栈已满 #include<iostream>using namespace std;#define Maxsize 100class stack{public: int a[Maxsize]; int top1; int top2;};void push(stack&A, int x

ACM找出一串数字是否能被分成两部分使其中一部分全部为负数,加上另一部分可以为0

Description Most financial institutions had become insolvent during financial crisis and went bankrupt or were bought by larger institutions, usually by banks. By the end of financial crisis of all the financial institutions only two banks still cont

管理中如何避免民主暴政--团队要分成两个大等级:为荣誉v&amp;s为活着两个等级

 这是在新浪的我写的原文,我修改一下放在这里,后续我还会详细描述相关的话题. http://blog.sina.com.cn/s/blog_769d900a0102v6c2.html 民主暴政其实是个大问题. 比如49年,如果用枪来作为选票,事实上,我们是民主的方式赢得了一个新的极权. 因为农民的数量远远多于地主. 但是,作为读者的你,是否认为我们的国家是民主国家呢? 有的公司,把民主彻底引入公司管理,比如,基层领导,由于选票来决定.然而上去的是一些和事佬.整个公司陷入停滞. 所以,民主是一

CSS中一个冒号和两个冒号有什么区别

在平时工作中用到伪类选择器的时候一个冒号和两个冒号貌似都是可以的,所以两者到底有什么区别呢,我们先来看下W3C关于CSS3选择器的规范中有一段描述: A pseudo-element is made of two colons (::) followed by the name of the pseudo-element. This :: notation is introduced by the current document in order to establish a discrimi

包含MIN函数的栈+一个数组实现两个堆栈+两个数组实现MIN栈

1.题目描述 定义栈的数据结构,请在该类型中实现一个能够得到栈最小元素的min函数. 思路:利用一个辅助栈来存放最小值 栈  3,4,2,5,1 辅助栈 3,2,1 每入栈一次,就与辅助栈顶比较大小,如果小就入栈,如果大就不入栈当前的辅助栈:当出栈时,辅助栈元素相等时也要出栈. class Solution { public: stack<int> mystack1;//辅助栈 stack<int> minstack;//最小栈 void push(int value) { if(

由“Java中一个字符占两个字节”引起

起因 Java中一个字符占两个字节,这和C/C++稍有区别.在C/C++中我们可以通过sizeof运算符方便地知道某个变量类型或对象的大小,那在Java中又如何? 问题出现 Java为什么没有提供sizeof运算符? 要回答这个问题,我们可以从另一个角度来看,那就是为什么C/C++中提供sizeof运算符.这就让人忍不住想到C/C++和Java在内存管理上的区别. 在C中,内存分配和释放的任务交给了程序员,当我们尝试用malloc为某个对象分配一块堆内存时,一个无法逃避的问题是,这个即将被创建的

关于伪类选择器中一个冒号和两个冒号的区别

在平时工作中用到伪类选择器的时候一个冒号和两个冒号貌似都是可以的,所以两者到底有什么区别呢,我们先来看下W3C关于CSS3选择器的规范中有一段描述: A pseudo-element is made of two colons (::) followed by the name of the pseudo-element. This :: notation is introduced by the current document in order to establish a discrimi