最大割详解poj-2531Network Saboteur(网络破坏者)

什么是最大割

你可以简单理解为:
割是图中定点的一个划分,它把图中的所有顶点划分成两个顶点集合S和T。
最大割就是令这两个集合之间割线权值最大
例如
红色圈中的两条边之和就是最大割
左边为S集合,右边为T集合
在这里插入图片描述
做法
分成两个子集S和T,一开始所有的点都在S集合里面,DFS遍历(回溯法)判断每一个点是继续留在S集合还是移动到T集合里面去,继续留在S里面的话对现有的代价总和没有影响。
移动到集合T的话就让现有的总和加上该点与集合S中其它所有点的边权,同时减去该点与集合T中所有其它点的边权:

for(int i=1;i<=n;i++)
{
	if(book[i])//判断
	num=num-mapp[x][i];
	else
	num=num+mapp[x][i];
}	

网络破坏者
时限: 2000MS 内存限制: 65536K
提交总数: 15890 接受: 7908
描述

一个大学网络由N台计算机组成。系统管理员收集有关节点之间流量的信息,并仔细将网络分为两个子网,以最大程度地减少各部分之间的流量。
一名心怀不满的计算机科学专业学生Vasya,被大学开除后,决定报仇。他入侵了大学网络,并决定重新分配计算机,以最大程度地提高两个子网之间的流量。
不幸的是,他发现计算如此最差的细分是他作为学生未能解决的问题之一。因此,他要求您,一个更成功的CS学生,帮助他。
交通数据以矩阵C的形式给出,其中Cij是在第i个节点与第j个节点之间发送的数据量(Cij = Cji,Cii = 0)。目的是将网络节点分为两个不相交的子集A和B,以使总和∑Cij(i∈A,j∈B)最大化。
输入值

输入的第一行包含多个节点N(2 <= N <= 20)。接下来的N行(每个行包含N个以空格分隔的整数)代表流量矩阵C(0 <= Cij <= 10000)。
输出文件必须包含一个整数-子网之间的最大流量。
输出量

输出必须包含一个整数-子网之间的最大流量。
样本输入

3
0 50 30
50 0 40
30 40 0
样本输出

90

#include<cstdio>
using namespace std;
int mapp[21][21],n,maxn,book[21];
void dfs(int x,int num,int flag)
{
for(int i=1;i<=n;i++)
{
	if(book[i])
	num=num-mapp[x][i];
	else
	num=num+mapp[x][i];
}	
if(maxn<num)
	maxn=num;
	if(flag==n)
	{
		return;
	}
	for(int i=x+1;i<=n;i++)
	{
	
		
			book[i]=1;
			flag++;
			
			dfs(i,num,flag);
			
			flag--;
			book[i]=0;
	
	}
}
int main() 
{
	scanf("%d",&n);
	for(int i=1;i<=n;i++)
	for(int j=1;j<=n;j++)
	{
		scanf("%d",&mapp[i][j]);
	}
	maxn=0;

	book[1]=1;
	dfs(1,0,1);	

	
printf("%d",maxn);
	return 0;
}
发布了44 篇原创文章 · 获赞 4 · 访问量 1063

猜你喜欢

转载自blog.csdn.net/qq_44162236/article/details/104096376
今日推荐