pku_2531_Network Saboteur dfs方法(94ms)、进位的方法(枚举)(1719ms)和随机化算法(313ms)
2010-08-23 20:19
513 查看
dfs搜索
//用进位的方法来枚举
//随机化算法
/*解法类型:随机化算法
题目大意: 把一个完全图分成两部分,使得连接这两部分边的权和最大。
解题思路: 随机改变一个点的位置,算出权和,重复200000次,取最大值输出。
提交情况: 1.Wrong Answer多次:随机的次数不够。
2. Time Limit Exceeded多次,由于每次都随机分配所有点的位置,所以随机次数稍多后就超时。
注意:这种方法用时较多,在poj上可以过,在zoj上过不了……
此题还可以用动态规划或应用巧妙的剪枝来做,可是我没找到方法……
*/
#include<iostream> using namespace std; int line[22],mx,n; int g[22][22]; bool flag[22]; int dfs(int k,int sum) { int sum1; if(k==n) { if(mx<sum) mx=sum; return 0; } if(mx<sum) mx=sum; for(int i=k;i<=n;i++) if(!flag[i]) { flag[i]=true; sum1=sum; sum1+=g[i][0]; for(int j=1;j<=n;j++) if(flag[j]) sum1-=2*g[i][j]; dfs(i+1,sum1); flag[i]=false; } return 0; } int main() { scanf("%d",&n); memset(flag,false,sizeof(flag)); for 4000 (int i=1;i<=n;i++) { g[i][0]=0; for(int j=1;j<=n;j++) { scanf("%d",&g[i][j]); g[i][0]+=g[i][j]; } } flag[1]=true; mx=g[1][0]; dfs(2,g[1][0]); printf("%d/n",mx); // system("pause"); return 0; }
//用进位的方法来枚举
Source Code Problem: 2531 User: X5 Memory: 248K Time: 1719MS Language: C++ Result: Accepted Source Code #include<iostream> using namespace std; int b[21],n; int G[21][21]; void slove(int b[]) { b ++; for(int i=n;i>0;i--) if(b[i]>1) { b[i]=0; b[i-1]++; } } int main() { int mx=0; while(cin>>n) { for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) cin>>G[i][j]; memset(b,0,sizeof(b)); b ++; while(b[0]==0) { int sum=0; for(int i=1;i<=n;i++) { if(b[i]==0) for(int j=1;j<=n;j++) if(b[j]) sum+=G[i][j]; } mx=max(mx,sum); slove(b); } cout<<mx<<endl; } return 0; }
//随机化算法
/*解法类型:随机化算法
题目大意: 把一个完全图分成两部分,使得连接这两部分边的权和最大。
解题思路: 随机改变一个点的位置,算出权和,重复200000次,取最大值输出。
提交情况: 1.Wrong Answer多次:随机的次数不够。
2. Time Limit Exceeded多次,由于每次都随机分配所有点的位置,所以随机次数稍多后就超时。
注意:这种方法用时较多,在poj上可以过,在zoj上过不了……
此题还可以用动态规划或应用巧妙的剪枝来做,可是我没找到方法……
*/
#include<iostream> using namespace std; int G[21][21]={0},part[30];//part数组用来将点分开 int main() { int n,i,j,a; while(cin>>n) { for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) cin>>G[i][j]; memset(part,0,sizeof(part)); int mx=-1,t=200000,sum=0;//t://随机的次数 while(t--) { a=rand()%n+1;//随机产生一个数,并得到于之对应的点的位置 part[a]=1-part[a];//改变这个点的位置 for(int i=1;i<=n;i++)//更新改变后图的权和 if(part[i]==part[a]) sum-=G[a][i]; else sum+=G[a][i]; mx=max(mx,sum); //更新最大值 } cout<<mx<<endl; } return 0; }
相关文章推荐
- pku 2531 Network Saboteur DFS
- 【Poj 2531】 Network Saboteur dfs
- POJ-2531--Network Saboteur---DFS深搜
- POJ 2531 Network Saboteur 位运算子集枚举
- DFS Network Saboteur poj 2531
- Network Saboteur poj 2531 dfs 简单搜索技巧和剪枝
- POJ-2531 Network Saboteur 枚举||随机化
- POJ -2531-Network Saboteur-DFS
- poj-2531 Network Saboteur DFS
- [POJ 2531]Network Saboteur[DFS]
- POJ2531-Network Saboteur-暴力枚举+记忆化/dfs/随机化乱搞
- 整数划分问题 【俩方法:1.dp 2.dfs枚举】
- [PKU] 1753 Flip Game [状态压缩,DFS/BFS,枚举]
- poj3628-DFS/0-1背包-DP/枚举-数据比较弱、方法比较多
- 【poj 2531】Network Saboteur 题意&题解&代码(C++)
- POJ 2531 Network Saboteur
- pku 2531 Network Saboteur(不会搜索,用的枚举)
- day3 POJ 2531 Network Saboteur
- poj2531(dfs)Network Saboteur
- POJ 2531 Network Saboteur [暴搜]