POJ2531——Network Saboteur(随机化算法水一发)

Network Saboteur


Description
A university network is composed of N computers. System administrators gathered information on the traffic between nodes, and carefully divided the network into two subnetworks in order to minimize traffic between parts.
A disgruntled computer science student Vasya, after being expelled from the university, decided to have his revenge. He hacked into the university network and decided to reassign computers to maximize the traffic between two subnetworks.
Unfortunately, he found that calculating such worst subdivision is one of those problems he, being a student, failed to solve. So he asks you, a more successful CS student, to help him.
The traffic data are given in the form of matrix C, where Cij is the amount of data sent between ith and jth nodes (Cij = Cji, Cii = 0). The goal is to divide the network nodes into the two disjointed subsets A and B so as to maximize the sum ∑Cij (i∈A,j∈B).
Input
The first line of input contains a number of nodes N (2 <= N <= 20). The following N lines, containing N space-separated integers each, represent the traffic matrix C (0 <= Cij <= 10000).
Output file must contain a single integer -- the maximum traffic between the subnetworks.
Output
Output must contain a single integer -- the maximum traffic between the subnetworks.
Sample Input
3
0 50 30
50 0 40
30 40 0
Sample Output
90

题目大意:

    把一个图用一条直线隔成两部分,求被这条直线相交的边的权值和的最大值。

解题思路:

    图论的无向完全图的最大割问题。

    先建立两个集合,一个集合包含全部的点,另一个为空集。

    此时的权值为0。

    随机选取一个点,将它从所在的集合挪到另外一个集合中。

    eg:

    当前状态的权值和为sum,将3号点,从集合1中挪到集合2中。

    则权值和的变化为

    sum+=edge[3][i],i表示在集合1中的点。

    sum-=edge[3][j],j表示在集合2中的点,不包括3号点。

    每进行一次变化,就会有新的sum产生,保存sum的最大值即可。

    (随机选择100W次后过得,随机次数越多,越可能产生标准答案,但要注意时间)

Code:

 1 /*************************************************************************
 2     > File Name: poj2531.cpp
 3     > Author: Enumz
 4     > Mail: 369372123@qq.com
 5     > Created Time: 2014年10月27日 星期一 19时08分08秒
 6  ************************************************************************/
 7 
 8 #include<iostream>
 9 #include<cstdio>
10 #include<cstdlib>
11 #include<string>
12 #include<cstring>
13 #include<list>
14 #include<queue>
15 #include<stack>
16 #include<map>
17 #include<set>
18 #include<algorithm>
19 #include<cmath>
20 #include<bitset>
21 #include<time.h>
22 #include<climits>
23 #define MAXN 100000
24 using namespace std;
25 void init()
26 {
27     srand(time(NULL));
28 }
29 int edge[50][50];
30 int main()
31 {
32     init();
33     int N;
34     while (cin>>N)
35     {
36         memset(edge,0,sizeof(edge));
37         for (int i=1;i<=N;i++)
38             for (int j=1;j<=N;j++)
39                 cin>>edge[i][j];
40         int times=1000000;
41         bool gather[50];
42         int ret=0,max=0;
43         memset(gather,0,sizeof(gather));
44         while (times--)
45         {
46             int tmp=rand()%N+1;
47             gather[tmp]=!gather[tmp];
48             for (int i=1;i<=N;i++)
49             {
50                 if (gather[i]!=gather[tmp])
51                     ret+=edge[i][tmp];
52                 if (gather[i]==gather[tmp]&&i!=tmp)
53                     ret-=edge[i][tmp];
54             }
55             max=max>ret?max:ret;
56         }
57         cout<<max<<endl;
58     }
59     return 0;
60 }

    

    

原文地址:https://www.cnblogs.com/Enumz/p/4062928.html