博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Vijos 1082 丛林探险
阅读量:6089 次
发布时间:2019-06-20

本文共 3544 字,大约阅读时间需要 11 分钟。

题目链接:

本题本来是练习SPFA的。我一看DIscuss能用裸搜。果断敲了一个前向星+DFS,居然超时了。后来发现是Next数组开小了,应该开成两倍边数的大小。

后来我又把前向星改成邻接表,也AC了。。最后写一发SPFA。

前向星+DFS+剪枝:(AC):

 

#include 
#include
#include
#include
#include
#include
#include
#include
using namespace std;#define INF 0x3f3f3f3f#define Maxn 5005#define Maxm 40005<<1struct Edge{ int x; int y; int c; int d;};Edge e[Maxm];int first[Maxn];int next[Maxm];//注意不要写成next[Maxn],切记int used[Maxn];int k;int s,t;int n,m;int mma = INF;void dfs(int start,int total_len,int total_k){ //加两个剪支,体力值超过范围或者长度必然不是最优两种情况 if(total_k > k || total_len > mma) { return; } if(start == t) { if(total_k<=k) { mma = mma>total_len ? total_len : mma; } return; } used[start] = 1; for(int i=first[start]; i!=-1; i=next[i]) { if(used[e[i].y] == 0) { dfs(e[i].y,total_len + e[i].d ,total_k + e[i].c); } } used[start] = 0;}int main(){/*#ifndef ONLINE_JUDGE freopen("in.txt","r",stdin);#endif*/ scanf(" %d %d",&n,&m); memset(first,-1,sizeof(first)); memset(next,-1,sizeof(next)); memset(used,0,sizeof(used)); int temp = m; int i = 0; while(temp--) { scanf(" %d %d %d %d",&e[i].x,&e[i].y,&e[i].c,&e[i].d); next[i] = first[e[i].x]; first[e[i].x] = i; i++; e[i].x = e[i-1].y,e[i].y = e[i-1].x,e[i].c = e[i-1].c,e[i].d = e[i-1].d; next[i] = first[e[i].x]; first[e[i].x] = i; i++; } scanf(" %d %d %d",&s,&t,&k); dfs(s,0,0); if(mma == INF) printf("-1\n"); else printf("%d\n",mma);}

 

邻接表+DFS+剪枝(AC):

 

#include 
#include
#include
#include
#include
#include
#include
#include
using namespace std;#define INF 0xffffff#define Maxn 5005#define Maxm 40005<<1struct vertex{ int n; int length; int cost;};vector < vertex > graph[Maxn];int used[Maxn];int k;int s,t;int n,m;int mma = INF;void dfs(int start,int total_len,int total_k){ //加两个剪支,体力值超过范围或者长度必然不是最优两种情况 if(total_k <=k && total_len < mma) { if(start == t) { mma = total_len; } else { used[start] = 1; for(int i=0; i

 

前向星+SPFA (AC):

声明两个Dist数组,一个代表时间(距离),一个代表体力值,只有两个Dist同时满足条件时,才会更新,也才有机会入队列。

 

#include 
#include
#include
#include
#include
#include
#include
#include
using namespace std;#define INF 0x3f3f3f3f#define Maxn 5005#define Maxm 40005<<1struct Edge{ int x; int y; int c; int d;};Edge e[Maxm];int first[Maxn];int next[Maxm];int used[Maxn];int distC[Maxn];//体力int distD[Maxn];//时间int k;int s,t;int n,m;void spfa(int s){ queue
q; memset(used,0,sizeof(used)); used[s] = 1; q.push(s); while(!q.empty()) { int u = q.front(); q.pop(); used[u] = 0; for(int i=first[u]; i!=-1; i=next[i]) { int v = e[i].y; int c = e[i].c; int d = e[i].d; if(distD[v] - d > distD[u] && distC[u] + c <=k) { distD[v] = distD[u] + d; distC[v] = distC[u] + c; if(used[v] == 0) { used[v] = 1; q.push(v); } } } }}int main(){ /*#ifndef ONLINE_JUDGE freopen("in.txt","r",stdin); #endif*/ scanf(" %d %d",&n,&m); memset(first,-1,sizeof(first)); memset(next,-1,sizeof(next)); memset(used,0,sizeof(used)); memset(distC,0x3f,sizeof(distC)); memset(distD,0x3f,sizeof(distD)); int temp = m; int i = 0; while(temp--) { scanf(" %d %d %d %d",&e[i].x,&e[i].y,&e[i].c,&e[i].d); next[i] = first[e[i].x]; first[e[i].x] = i; i++; e[i].x = e[i-1].y,e[i].y = e[i-1].x,e[i].c = e[i-1].c,e[i].d = e[i-1].d; next[i] = first[e[i].x]; first[e[i].x] = i; i++; } scanf(" %d %d %d",&s,&t,&k); distD[s] = distC[s] = 0; spfa(s); if(distD[t] == INF) printf("-1\n"); else printf("%d\n",distD[t]);}

 

 

转载地址:http://gblwa.baihongyu.com/

你可能感兴趣的文章
Docker Swarm的前世今生
查看>>
从0开始构建自己的前端知识体系-不要对"=="说不
查看>>
Python 从零开始爬虫(七)——实战:网易云音乐评论爬取(附加密算法)
查看>>
Java设计模式--单例模式
查看>>
JS 实现文字滚动显示
查看>>
php实现依赖注入(DI)和控制反转(IOC)
查看>>
【EASYDOM系列教程】之遍历节点
查看>>
RecyclerView添加分割线的简便方法
查看>>
HTTP状态码: 301/302/303/307
查看>>
如何搭建高质量、高效率的前端工程体系--页面结构继承
查看>>
白山云科技 CTO 童剑:空降后,如何有技术又有艺术地破局?
查看>>
Google发布App Engine第二代运行时,提供Python 3.7和PHP 7.2支持
查看>>
通过XAML Islands使Windows桌面应用程序现代化
查看>>
Mozilla开发全新的公开网络API WebXR 来实现增强现实
查看>>
人脸识别技术的真相
查看>>
GitHub Checks API帮助应用实现进一步的持续集成
查看>>
微软宣布支持基于虚拟机的Azure IOT Edge服务
查看>>
企业级Java应用最重要的4个性能指标
查看>>
对谈Jason Fox:如何导向探索
查看>>
网易云基于Prometheus的微服务监控实践
查看>>