标签:
Time Limit: 2000MS | Memory Limit: 65536K | |
Total Submissions: 9580 | Accepted: 4560 |
Description
Input
Output
Sample Input
3 0 50 30 50 0 40 30 40 0
Sample Output
90
题意:将给定图分成两个子图A,B,使A中结点i到B中结点j的距离和最大,输出最大值
初看以为是图论题,原来可以直接dfs过。。直接dfs递归枚举顺便剪枝
//poj2531_dfs递归枚举 #include<iostream> #include<cstdlib> #include<cstdio> #include<cstring> #include<algorithm> #include<queue> using namespace std; const int maxn=30; int N,C[maxn][maxn]; int dist[maxn]; int ans; bool vis[maxn];//1表示在集合A,0表示还在集合B void dfs(int cur,int step,int limit,int sum) { if(cur+limit-step>N) return;//这个剪枝貌似有点弱,只是从256ms优化到了188ms for(int i=1;i<=N;i++){ //从B添加结点cur掉A中 if(vis[i]) sum-=C[cur][i];//减少到A的边 else sum+=C[cur][i];//增加到B的边 } if(step==limit){ //到达限制,比较ans,返回 if(sum>ans) ans=sum; return; } vis[cur]=1; for(int i=cur+1;i<=N;i++){ dfs(i,step+1,limit,sum); //添加下一个 } for(int i=1;i<=N;i++){ //从A中拿回来 if(vis[i]) sum+=C[cur][i]; else sum-=C[cur][i]; } vis[cur]=0;//记得还原vis } int main() { while(cin>>N){ for(int i=1;i<=N;i++){ for(int j=1;j<=N;j++){ cin>>C[i][j]; dist[i]+=C[i][j]; } } ans=0; for(int i=1;i<=N/2;i++){ //枚举A中的结点个数 for(int st=1;st<=N;st++){ //递归枚举,st为起点 memset(vis,0,sizeof(vis)); dfs(st,1,i,0); } } cout<<ans<<endl; } return 0; }
标签:
原文地址:http://www.cnblogs.com/--560/p/4335087.html