zoukankan      html  css  js  c++  java
  • 1340C.Nastya and Unexpected Guest(最短路+dp+01BFS优化)

    题意:

    一条路长度为n

    从0出发,有m个站点

    绿灯红灯交替变换

    绿灯的时候必须走

    从一个站点出来后方向不能变

    红灯的时候必须站在一个站点上

    求最短多少时间可以到达n点

    题解:

    定义(f(i,j))为到第(i)个站点时,绿灯当前时间为(j),经过了最少轮数红绿灯变色

    那么(f(i,j))可以往后转移

    (f(i-1,j+x)) (f(i+1,j+y)) (f(i,0))

    根据题意写转移即可。

    这个转移方程要求的是最少轮数,所以就是一个广义的最短路模型。但是这题直接跑(nlogm)的最短路是会被卡掉的。

    这里介绍一种基于01图的最短路求解方法,用双端队列代替优先队列做一个01BFS,时间复杂度是(O(n+m))

    
    
    //定义f(i,j)为到第i个站点时,绿灯当前时间为j,经过了最少轮数红绿灯变色
    //那么f(i,j)可以往后转移
    //f(i-1,j+x) f(i+1,j+y) f(i-1,0) f(i+1,0)
    #include<bits/stdc++.h>
    using namespace std;
    int n,m,g,r;
    int f[10100][1010];
    int vis[10100][1010];
    int a[10100];
    struct qnode {
    	int x;
    	int y;
    	qnode (int xx,int yy) {
    		x=xx;
    		y=yy;
    	}
    }; 
    long long bfs () {
    	deque<qnode> q;
    	q.push_back(qnode(0,0));
    	vis[0][0]=1;
    	long long ans=1e18;
    	while (q.size()) {
    		qnode tt=q.front();
    		q.pop_front();
    		if (tt.y==0) {
    			//如果当前绿灯时间刚刚开始
    			//看看能不能直接走到终点 
    			int t1=n-a[tt.x];
    			if (t1<=g) {
    				long long tmp=1ll*f[tt.x][tt.y]*(g+r)+t1;
    				ans=min(ans,tmp);
    			}
    		}
    		if (tt.y==g) {
    			if (!vis[tt.x][0]) {
    				f[tt.x][0]=f[tt.x][tt.y]+1;
    				vis[tt.x][0]=1;
    				q.push_back(qnode(tt.x,0));
    			} 
    			continue;
    		}
    		if (tt.x>1) {
    			//如果不在1号点
    			//可以往回走 
    			int x=tt.x-1;
    			int y=tt.y+a[tt.x]-a[x];
    			if (y<=g&&!vis[x][y]) {
    				vis[x][y]=1;
    				f[x][y]=f[tt.x][tt.y];
    				q.push_front(qnode(x,y));
    			}
    		}
    		if (tt.x<m) {
    			//如果不在m号点
    			//可以往后走
    			int x=tt.x+1;
    			int y=tt.y+a[x]-a[tt.x];
    			if (y<=g&&!vis[x][y]) {
    				vis[x][y]=1;
    				f[x][y]=f[tt.x][tt.y];
    				q.push_front(qnode(x,y));
    			}
    		}
    	}
    	if (ans==1e18) ans=-1;
    	return ans;
    }
    int main () {
    	scanf("%d%d",&n,&m);
    	for (int i=1;i<=m;i++) scanf("%d",a+i);
    	scanf("%d%d",&g,&r);
    	sort(a+1,a+m+1);
    	printf("%lld
    ",bfs());
    }
  • 相关阅读:
    700. Search in a Binary Search Tree
    100. Same Tree
    543. Diameter of Binary Tree
    257. Binary Tree Paths
    572. Subtree of Another Tree
    226. Invert Binary Tree
    104. Maximum Depth of Binary Tree
    1、解决sublime打开文档,出现中文乱码问题
    移植seetafaceengine-master、opencv到ARM板
    ubuntu16.04-交叉编译-SeetaFaceEngine-master
  • 原文地址:https://www.cnblogs.com/zhanglichen/p/14352751.html
Copyright © 2011-2022 走看看