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 }

 

你可能感兴趣的:(poj)