Network Saboteur(Rand版)

poj2531:http://poj.org/problem?id=2531

题意:给你一个图,图中点之间会有边权,现在问题是把图分成两部分,使得两部分之间边权之和最大。
题解:随机算法

#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
using namespace std;
int n;
int g[30][30];
int vis[30];
const int Timelimit=2000;//时间限制是2000
int main(){
   scanf("%d",&n);
   for(int i=1;i<=n;i++)
    for(int j=1;j<=n;j++)
      cin>>g[i][j];
   memset(vis,0,sizeof(vis));//0表示全部属于一个集合
   int Time=Timelimit*50;//随机次数,这个字数不能太少,如果改成*10就过不了
   int counts=0;//当前的最大值
   int maxn=0;//最大值
   while(Time--){
     int x=rand()%n+1;//产生随机数,注意,这里是1--n,所以要注意范围
       vis[x]=!vis[x];//改变当前的x所属的集合
       for(int i=1;i<=n;i++){
        if(vis[i]!=vis[x])//对于改变之后的x要统计新增加的边
            counts+=g[i][x];
        if(i!=x&&vis[i]==vis[x])//对于改变之后的x,之前与x不在一个集合点,这些点之间边现在要删除
            counts-=g[i][x];
       }
       if(counts>maxn)//更新最大值
        maxn=counts;
   }
   printf("%d
",maxn);
}
View Code
原文地址:https://www.cnblogs.com/chujian123/p/3533156.html