poj2531_最大割随机算法
题意:把一个完全图分成两部分,使得连接这两部分边的权和最大。
分析:
图论的无向完全图的最大割问题可以用 随机化算法 Random Algorithm 去做。
参考http://blog.csdn.net/lyy289065406/article/details/6648571
代码:
View Code
1 #include <iostream> 2 #include <memory.h> 3 #include <stdio.h> 4 //#include <time.h> 5 #include <stdlib.h> 6 using namespace std; 7 8 const int maxnum=21; 9 int array[maxnum][maxnum]; 10 bool set[maxnum]; 11 int n,sum; 12 int timelimit=2000; //ms,本题的限制时间 13 14 int main() 15 { 16 scanf("%d",&n); 17 int i,j; 18 for(i=1;i<=n;i++) 19 for(j=1;j<=n;j++) 20 scanf("%d",&array[i][j]); 21 22 //随机算法 23 int temp,x; 24 int time=timelimit*100; //使随机次数尽可能大 25 sum=0; //最大割的权值之和 26 temp=0; //当前边割集权和 27 memset(set,false,sizeof(set)); 28 while(time--) 29 { 30 // temp=0; 这里不对啊。 31 x=rand()%n+1;//生成随机数 x,对应于总集合的某个结点x 32 //注意由于使用的结点序号为1~n,对应了数组下标,下标为0的数组元素没有使用 33 //那么这里必须+1,因为若rand()=n,那么再对n取模结果就为0 34 35 set[x]=!set[x]; //改变x所在的集合位置 36 for(i=1;i<=n;i++) 37 { 38 if(set[x]!=set[i]) //结点i 和 x分别在两个集合内 39 temp+=array[x][i];//就是说因为x所在集合的改变,使得割边的个数增加 40 //割集的原权值 要加上 当前新加入的割边(i,x)的权值 41 if(i!=x && set[x]==set[i]) //结点i 和 x分别在相同的集合内,但他们不是同一元素 42 temp-=array[x][i];//就是说因为x所在集合的改变,使得割边的个数减少 43 //割集的原权值 要减去 当前失去的割边(i,x)的权值 44 } 45 if(temp>sum) 46 sum=temp; 47 } 48 printf("%d\n",sum); 49 return 0; 50 }