标签:
Time Limit: 2000MS | Memory Limit: 65536K | |
Total Submissions: 9504 | Accepted: 4509 |
Description
Input
Output
Sample Input
3 0 50 30 50 0 40 30 40 0
Sample Output
90
Source
找出n个点的最大割。
#include <cstdio> #include <cstring> #include <algorithm> using namespace std ; int Map[25][25] , max1 ; int state[25] , n ; void dfs(int u,int sum) { if( u == n ) { max1 = max(max1,sum) ; return ; } dfs(u+1,sum) ; state[u] = 1 ; int i ; for(i = 0 ; i < n ; i++) { if( state[i] ) { sum -= Map[u][i] ; } else sum += Map[u][i] ; } dfs(u+1,sum) ; state[u] = 0 ; } int main() { int i , j ; while( scanf("%d", &n) != EOF ) { memset(state,0,sizeof(state)) ; for(i = 0 ; i < n ; i++) for(j = 0 ; j < n ; j++) scanf("%d", &Map[i][j]) ; max1 = 0 ; dfs(0,0) ; printf("%d\n", max1) ; } return 0; }
看的网上小优的博客,随机化搜索。。。。
#include<iostream> using namespace std; const int TimeLimit=2000; //本题时间限制为2000ms int main(int i,int j) { int n; while(cin>>n) { /*Input*/ int w[30][30]={0}; for(i=1;i<=n;i++) for(j=1;j<=n;j++) { cin>>w[i][j]; w[j][i]=w[i][j]; //双向完全图 } /*Random Algorithm*/ bool subset[30]={false}; //A集:true B集:false int time=TimeLimit*100; //使随机次数尽可能大,随机结果尽可能接近最优解 long max_w=0; //最大割的权值之和 long sum=0; //当前边割集权和 while(time--) { int x=rand()%n+1; //生成随机数 x,对应于总集合的某个结点x //注意由于使用的结点序号为1~n,对应了数组下标,下标为0的数组元素没有使用 //那么这里必须+1,因为若rand()=n,那么再对n取模结果就为0 //这时就会导致使用了不存在的 [0]结点,本应使用的 [n]结点就被丢弃了 subset[x]=!subset[x]; //改变x所在的集合位置 for(int i=1;i<=n;i++) //由于是完全图,所以每个顶点i都与x相关联,因此要全部枚举 { if(subset[i]!=subset[x]) //结点i 和 x分别在两个集合内 sum+=w[i][x]; //就是说因为x所在集合的改变,使得割边的个数增加 //割集的原权值 要加上 当前新加入的割边(i,x)的权值 if(i!=x && subset[i]==subset[x]) //结点i 和 x分别在相同的集合内,但他们不是同一元素 sum-=w[i][x]; //就是说因为x所在集合的改变,使得割边的个数减少 //割集的原权值 要减去 当前失去的割边(i,x)的权值 } if(max_w < sum) max_w = sum; } cout<<max_w<<endl; } return 0; }
poj2531--Network Saboteur(搜索练习7-dfs或随机算法)
标签:
原文地址:http://blog.csdn.net/winddreams/article/details/42980293