vijos1082 丛林探险(最短路+搜索)
2017-02-27 19:31
260 查看
题目大意:一个无向图中每一条路有两个属性:体力和路径长.给出一个最大体力值k在满足不大于最大体力值的情况下求一条最短路径.
数据范围:n(<=5000) m(<=40000)
分析:以体力值跑一边最短路,因为m+n只有45000,所以考虑搜索每一条从s->t的路径.
并进行剪枝:
{可行性剪枝:若此时消耗的体力值+下一条路消耗的体力值>最大体力值
最优化剪枝:若此时走过的路径长>=ans
}
code
数据范围:n(<=5000) m(<=40000)
分析:以体力值跑一边最短路,因为m+n只有45000,所以考虑搜索每一条从s->t的路径.
并进行剪枝:
{可行性剪枝:若此时消耗的体力值+下一条路消耗的体力值>最大体力值
最优化剪枝:若此时走过的路径长>=ans
}
code
#include<iostream> #include<cstdio> #include<cmath> #include<cstring> #include<algorithm> #include<cstdlib> #include<queue> #define fo(i,a,b) for(int i=a;i<=b;i++) #define fod(i,a,b) for(int i=a;i>=b;i--) using namespace std; const int MAXN=5e3+10; const int MAXM=4e5+10; const int INF=0x3f3f3f; int last[MAXN],len=0,n,m,dis[MAXN],k,s,t; int ans=INF; bool vis[MAXN]; struct edge{ int to,val,next,blood; edge(int to=0,int val=0,int next=0,int blood=0):to(to),val(val),next(next),blood(blood){} }e[MAXM*2]; void add(int from,int to,int val,int blood){ e[++len]=edge(to,val,last[from],blood); last[from]=len; } void Spfa(int s){ fo(i,1,n) dis[i]=INF; memset(vis,0,sizeof(vis)); dis[s]=0; deque<int>q; q.push_front(s); vis[s]=1; while(!q.empty()){ int cur=q.front(); q.pop_front(); vis[cur]=0; for(int i=last[cur];i;i=e[i].next){ int id=e[i].to; if(dis[id]>dis[cur]+e[i].blood){ dis[id]=dis[cur]+e[i].blood; if(!vis[id]){ vis[id]=1; if(q.empty()){ q.push_front(id); } else{ if(dis[id]<dis[q.front()]) q.push_front(id); else q.push_back(id); } } } } } } void dfs(int cur,int dist,int blood){ if(cur==t) {ans=dist;return ;} for(int i=last[cur];i;i=e[i].next){ int id=e[i].to; if(dist+e[i].val>=ans||dis[id]+e[i].blood>blood) continue; vis[id]=1; dfs(id,dist+e[i].val,blood-e[i].blood); vis[id]=0; } } int main(){ scanf("%d%d",&n,&m); int x,y,c,d; fo(i,1,m){ scanf("%d%d%d%d",&x,&y,&c,&d); add(x,y,d,c); add(y,x,d,c); } scanf("%d%d",&s,&t); Spfa(t); memset(vis,0,sizeof(vis)); scanf("%d",&k); if(dis[s]>k) printf("-1"); else{ vis[s]=1; dfs(s,0,k); vis[s]=0; printf("%d",ans); } return 0; }
相关文章推荐
- [Vijos1082 丛林探险]
- Vijos 1082 丛林探险
- Vijos 1082 丛林探险
- Vijos——T 1082 丛林探险
- Vijos 1082 最短路
- A*(伪——vijos丛林探险
- 【vijos】P1082丛林探险DFS+剪枝版本
- VIJOS:P1082丛林探险
- 【搜索】丛林探险
- 【BZOJ2407/4398】探险/福慧双修 最短路建模
- 【BZOJ 2541】【Vijos 1366】【CTSC 2000】冰原探险
- Vijos1029[晴天小猪历险记之Number] 搜索+康托展开
- HDU 3143 Speedy Escape(最短路+二分+搜索)
- BZOJ 1082 栅栏 [二分+搜索]
- 最短路 + 搜索 + 剪枝 之 hdu 4848 Wow! Such Conquering!
- vijos 1082
- HDU 1428 最短路+记忆化搜索
- vijos-p1599 货币 -记忆化搜索
- 数据结构实验报告-图算法-最小生成树-最短路-拓扑排序-搜索
- uva 10603倒水问题(搜索 隐式图的最短路 )