什么是最大割
你可以简单理解为:
割是图中定点的一个划分,它把图中的所有顶点划分成两个顶点集合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;
}