poj 3411 搜索+剪枝
来源:互联网 发布:怎样判断网络通不通 编辑:程序博客网 时间:2024/05/21 15:44
记忆化搜索:s[status][cur] 记录在当前状态下,此刻位于cur点,到目的地所要的花费,由于一旦状态和位置确定,这个值是一定的
二进制状态表示:注意到n,m都比较小,由此启发
有一个剪枝:防止impossible时与目的地不连通而产生无限循环,
有m条边,对于每条边,最多存放在m个环中,故为m*m
#include <iostream>#include <cstring>#include <cstdlib>#include <cstdio>#include <vector>using namespace std;#define INF 10000000struct pp{int b,c,p,r;pp(){b=c=p=r=0;}pp(int _b,int _c,int _p,int _r){b=_b;c=_c;p=_p;r=_r;}};int n,m;int vis[2500][11];int s[2500][11];vector<pp>vec[100];int min(int aa,int bb){return aa<bb?aa:bb;}int ans;int renew(int status,int pos){return status|(1<<(pos-1));}bool isvis(int status ,int pos){return status&(1<<(pos-1));}int dfs(int cur,int status,int cost){if(s[status][cur]!=-1)return s[status][cur];if(cur==n)return 0;vis[status][cur]++;int tt,sstatus,temp;int ret=INF;if(vis[status][cur]>m*m)return INF;for(int i=0;i<vec[cur].size();++i){tt=INF;sstatus=renew(status,vec[cur][i].b);if(isvis(status,vec[cur][i].c))tt=dfs(vec[cur][i].b,sstatus,cost+vec[cur][i].p);temp=dfs(vec[cur][i].b,sstatus,cost+vec[cur][i].r);if(tt<temp)s[sstatus][vec[cur][i].b]=tt;else s[sstatus][vec[cur][i].b]=temp;if(tt+vec[cur][i].p<temp+vec[cur][i].r)ret=min(ret,tt+vec[cur][i].p);else ret=min(ret,temp+vec[cur][i].r);}return ret;}int main (){//freopen("aa.txt","r",stdin);//freopen("bb.txt","w",stdout);while(scanf("%d%d",&n,&m)!=EOF){for(int i=0;i<=n;++i)vec[i].clear();int a,b,c,p,r;for(int i=1;i<=m;++i){scanf("%d%d%d%d%d",&a,&b,&c,&p,&r);vec[a].push_back(pp(b,c,p,r));}ans=INF;memset(vis,0,sizeof(vis));memset(s,-1,sizeof(s));ans=dfs(1,1,0);if(ans>=INF)printf("impossible\n");elseprintf("%d\n",ans);}//system("pause");return 0;}
后来研究出更简洁的代码,因为参考了网上的代码,但发现这是错的
网上有人用了个强剪枝 vis[cur]>3 ,即不允许在同一条1-n的走的路径上走过一个环3次,
但下面这组数据程序就过不了,虽然在poj上过了
6 9
1 2 1 1 1
2 1 2 1 1
1 3 2 1 100
3 1 3 1 1
1 4 3 1 100
4 1 4 1 1
1 5 4 1 100
5 1 5 1 1
1 6 5 1 100
所以应该 vis[cur]>m*m
#include <iostream>#include <cstring>#include <cstdlib>#include <cstdio>#include <vector>using namespace std;#define INF 10000000struct pp{int b,c,p,r;pp(){b=c=p=r=0;}pp(int _b,int _c,int _p,int _r){b=_b;c=_c;p=_p;r=_r;}};int n,m,ans,vis[15];bool flag;vector<pp>vec[100];int min(int aa,int bb){return aa<bb?aa:bb;}void dfs(int cur,int cost){if(cost>=ans||vis[cur]>m*m)return ;if(cur==n){flag=true;ans=cost;return;}vis[cur]++;for(int i=0;i<vec[cur].size();++i){if(vis[vec[cur][i].c])dfs(vec[cur][i].b,cost+vec[cur][i].p);dfs(vec[cur][i].b,cost+vec[cur][i].r);}vis[cur]--;}int main (){//freopen("aa.txt","r",stdin);//freopen("bb.txt","w",stdout);while(scanf("%d%d",&n,&m)!=EOF){for(int i=0;i<=n;++i)vec[i].clear();int a,b,c,p,r;for(int i=1;i<=m;++i){scanf("%d%d%d%d%d",&a,&b,&c,&p,&r);vec[a].push_back(pp(b,c,p,r));}ans=INF;flag=false;memset(vis,0,sizeof(vis));dfs(1,0);if(ans>=INF)printf("impossible\n");elseprintf("%d\n",ans);}system("pause");return 0;}
- poj 3411 搜索+剪枝
- POJ - 1011 搜索剪枝
- poj 1411(搜索+剪枝)
- poj 1191 搜索+剪枝
- poj 1190 搜索+剪枝
- POJ 1011 搜索剪枝
- poj 2078(搜索+剪枝)
- poj 1948(搜索+剪枝)
- poj 生日蛋糕 搜索+剪枝
- POJ 1724 ROADS (搜索+剪枝)
- poj 1011 Sticks(搜索+剪枝)
- POJ 1011 STICKS 搜索 剪枝
- POJ 1011 Sticks(搜索+剪枝)
- poj 2362 square-----搜索+剪枝
- POJ 2531(搜索剪枝)
- 搜索 + 剪枝 --- POJ 1101 : Sticks
- poj 1011 搜索(剪枝)
- POJ 2362 Square(搜索+剪枝)
- 03 设计模式之--修饰设计模式
- FILETIME使用,获取文件的创建时间,修改时间和访问时间
- delphi 7在win7下运行出现'C:\program Files\\Borland\Delphi7\Bin\delphi32.$$$'的改正
- spoj 1470 Another Sequence Problem
- 没有文件扩展“.js”的脚本引擎 解决
- poj 3411 搜索+剪枝
- OpenCV+VS2010+JavaCV+Eclipse+Win7
- 从技术走向IT管理
- 打理一下IOS项目中的图片资源
- 转: HP大中华区总裁孙振耀退休感言--你没有读,继续走弯路的你不要怪我
- 火箭球迷惊讶林书豪是韩国人 称这个笑话不好笑
- 黑马程序员01——.NET框架基本介绍
- 《JavaWeb---JQuery淡入淡出效果的实现》
- poj 3522 Slim Span