线性规划与网络流24题:《汽车加油行驶问题》
来源:互联网 发布:淘宝销量排行榜2015 编辑:程序博客网 时间:2024/04/29 23:05
基于分层思想的最短路问题,将一维问题转化为多维空间中的问题解决!
分层思想很重要,一定要牢记啊!
它的优势就是在于把限制条件中的变量扩充,这样就解决了好多不确定的问题!可以建图的时候就方便多了!
算法思想:说到这个题目,应该说是刚开始的时候被他给吓到了,只是想着如何去把所有的条件构造起来,然后使用网络流的方式来解决问题!但是,如果真的是很冷静下来好好地思考这道题目,就会发现如果没有那些限制条件,就是一个求解最长路的题目,这样就可以直接使用SPFA来解决这个问题!关键就是在于这个每次最多只能走K个网格边,这样就是限制了活动的范围,使得有的边无法扩展!因此可以考虑使用这个分层思想的最短路问题!就是通过将每一个点进行拆分,这样,就是相当于一种分类讨论的方式!而分类讨论了之后,就知道哪些边是可以扩展的,哪些边是不能扩展的!关键点就是在于该如何选取变量来分层,这就是因情况而异了!像这道题目之中,就是通过油量的多少来扩展边的!分层思想,说穿了其实就是相当于这个动态规划之中的增加变量的方式来确定状态一样,他们的实质其实都是一样的!
本题之所以出现了比较多的问题:
总结下来,其实是有两点的啊!一点,就是这个距离刚开始在初始化的时候,没有看清楚s的范围,导致初始化的时候出现了一些问题!还有,就是一点,那就是这个理解题意出错了!!把这个加油理解成了经过这个点的时候,可以加上,也可以不加,但是,其实,题目的意思是一定要加上的啊!这一点搞得我花了好长的时间调试啊!
感觉自己最近有进步了不少啊!
粘贴代码:
#include<iostream>#include<cstdio>#include<cstdlib>#include<cstring>using namespace std;#define maxN 110000#define maxE 2000000#define maxsize 1000000#define INF 1<<30struct Edge{ int u,v,w,next;};Edge edge[maxE];int cnt=0;int q[maxsize];bool mat[110][110];int N,A,B,C,K;int c[2]={0,0};int s,t;const int dx[]={-1,0,1,0};const int dy[]={0,-1,0,1};int index(int k,int x,int y){ return k*N*N+N*x+y;}int head[maxN],d[maxN];bool vis[maxN];void addedge(int u,int v,int w){ edge[cnt].u=u; edge[cnt].v=v; edge[cnt].w=w; edge[cnt].next=head[u]; head[u]=cnt++;}void SPFA(){ memset(vis,0,sizeof(vis)); for(int i=0;i<=t;i++) d[i]=INF; d[s]=0; vis[s]=true; int l=0,r=0; q[r++]=s; while(l<r){ int u=q[l%maxsize]; l++; vis[u]=0; for(int j=head[u];j!=-1;j=edge[j].next){ int v=edge[j].v; if(edge[j].w+d[u]<d[v]){ d[v]=d[u]+edge[j].w; if(!vis[v]){ vis[v]=1; q[r%maxsize]=v; r++; } } } }} int main(){ //freopen("oil.txt","r",stdin); scanf("%d%d%d%d%d",&N,&K,&A,&B,&C); s=index(K,1,1); t=index(K,N,N); c[0]=C; int i,j; for(i=1;i<=N;i++) for(j=1;j<=N;j++) scanf("%d",&mat[i][j]); int k; memset(head,-1,sizeof(head)); for(k=0;k<=K;k++) for(i=1;i<=N;i++) for(j=1;j<=N;j++){ int temp=index(k,i,j); if(k==0) addedge(temp,index(K,i,j),A+c[mat[i][j]]); else{ for(int dir=0;dir<4;dir++){ int x=i+dx[dir]; int y=j+dy[dir]; if(x>=1 && x<=N && y>=1 && y<=N){ if(dir<=1){ if(mat[x][y]) addedge(temp,index(K,x,y),B+A); else addedge(temp,index(k-1,x,y),B); } else{ if(mat[x][y]) addedge(temp,index(K,x,y),A); else addedge(temp,index(k-1,x,y),0); } } } if(k!=K) addedge(temp,index(K,i,j),A+c[mat[i][j]]); } } SPFA(); int ans=INF; for(k=0;k<=K;k++){ if(d[index(k,N,N)]<ans){ ans=d[index(k,N,N)]; } } printf("%d\n",ans); return 0;}
0 0
- 线性规划与网络流24题:《汽车加油行驶问题》
- 【线性规划与网络流24题】汽车加油行驶问题 分层图
- 【网络流24题】汽车加油行驶问题
- 网络流24题15. 汽车加油行驶问题
- 网络流24题之T15 汽车加油行驶问题
- 【线性规划与网络流24题 15】汽车加油
- [网络流24题-15] 汽车加油行驶 - 分层图
- cogs 737. [网络流24题] 汽车加油行驶
- 网络流24题 之十五 汽车加油行驶问题 分层图
- loj6223「网络流 24 题」汽车加油行驶问题(分层图spfa)
- 汽车行驶加油问题
- 汽车加油行驶问题
- 汽车加油行驶问题
- 汽车加油行驶问题
- 【网络流24题】汽车加油行驶(分层图+最短路)
- 【dp】汽车加油行驶问题
- 汽车加油行驶问题专题
- [codevs 1912] 汽车加油行驶问题
- 端口号的理解
- HDU 2076 夹角有多大(题目已修改,注意读题)
- 找工作笔试面试那些事儿(16)---linux相关知识点(1)
- Hibernate调试——定位查询源头
- 0cfnQUEyqHS
- 线性规划与网络流24题:《汽车加油行驶问题》
- 细说UI线程和Windows消息队列
- HDU 2077 汉诺塔IV
- binutils使用错误:this linker was not configured to use sysrootscollect2:ld returned 1 exit status
- spring技术内幕16-Spring具体事务处理器的实现
- Codeforces Round #257 (Div. 1)-A,B,C
- 在Ubuntu 14.04和CentOS上安装boost1.55二进制包
- “娘,你怎么了吗?”常芸芸撒娇道。这丫头,
- HDU 题目3008 Warcraft