• [01bfs]


    bfs可以O(V+E)求解边权全为1的图上最短路。
    而当边权只有0或1时,使用其它最短路算法是有些浪费的,此时可以使用bfs的变种:0-1 bfs来快速求解,复杂度仍为O(V+E).

    D. Labyrinth(CF 1064D)

    给你一个n*m的迷宫,给出起始点,向左不超过L,向右不超过R。

    求最多能走到的点的个数。

    当我们单纯的dfs(int x,int y,int L,int R)  //起点,L,R的时候,肯定会tle 的

    我们可知,从起始点开始,向上向下的消耗的价值,也就是边权都为0,而向左向右的边权都为1.

    这时,只有0和1的图就可以用 01bfs来写。

    用一个双端队列。deque<node>que。(node结点来储存信息和限制条件)

    当边权为0时,就把这个点加入顶端。当边权为1时,把点加入尾端。

    que.push_front();  que.pop_front();

    que.push_back();

    这道题就从起始点开始遍历,上下两个点加入顶端,左右两个点加入尾端。

    求最多能遍历到的点的个数就可以了。

    因为每个点最多只可能遍历一次,因此可以省去bok数组。

     1 #include <iostream>
     2 #include <cstdio>
     3 #include <cmath>
     4 #include <algorithm>
     5 #include <set>
     6 #include <queue>
     7 #include <stack>
     8 #include <string>
     9 #include <cstring>
    10 #include <vector>
    11 #include <map>
    12 #include<ctime>
    13 //#include <unordered_map>
    14 #define mem( a ,x ) memset( a , x ,sizeof(a) )
    15 #define rep( i ,x ,y ) for( int i = x ; i<=y ;i++ )
    16 #define lson  l ,mid ,pos<<1
    17 #define rson mid+1 ,r ,pos<<1|1
    18 using namespace std;
    19 typedef long long ll ;
    20 typedef pair<int ,int> pii;
    21 typedef pair<ll ,int> pli;
    22 const int inf = 0x3f3f3f3f;
    23 const ll mod=998244353;
    24 const int N=100000+50;
    25 int n,m,r,c,L,R;
    26 char s[2010][2010];
    27 int bok[2010][2010];
    28 int xx[4]={0,0,1,-1};
    29 int yy[4]={1,-1,0,0};
    30 struct node
    31 {
    32     int x,y,l,r;
    33 }e;
    34 deque<node>que;
    35 int check(int xx,int yy)
    36 {
    37     if(xx<1||xx>n||yy<1|yy>m||bok[xx][yy]==1||s[xx][yy]=='*')
    38         return 0;
    39     return 1;
    40 }
    41 void dfs()
    42 {
    43     bok[r][c]=1;
    44     que.push_front({r,c,L,R});
    45     while(!que.empty())
    46     {
    47         e=que.front();    que.pop_front();
    48         //cout<<e.x<<" "<<e.y<<" "<<e.l<<" "<<e.r<<endl;
    49         for(int i=2;i<4;i++)
    50         {
    51             int _x=e.x+xx[i],_y=e.y+yy[i];
    52             if(check(_x,_y))
    53             {
    54                 bok[_x][_y]=1;
    55                 que.push_front({_x,_y,e.l,e.r});
    56             }
    57         }
    58         int _x=e.x+xx[1],_y=e.y+yy[1];
    59         if(check(_x,_y)&&e.l)
    60             {
    61                 bok[_x][_y]=1;
    62                 que.push_back({_x,_y,e.l-1,e.r});
    63             }
    64         _x=e.x+xx[0],_y=e.y+yy[0];
    65         if(check(_x,_y)&&e.r)
    66             {
    67                 bok[_x][_y]=1;
    68                 que.push_back({_x,_y,e.l,e.r-1});
    69             }
    70     }
    71 
    72 }
    73 int main()
    74 {
    75     scanf("%d%d%d%d%d%d",&n,&m,&r,&c,&L,&R);
    76     for(int i=1;i<=n;i++)
    77         scanf("%s",s[i]+1);
    78     dfs();
    79     int ans=0;
    80     for(int i=1;i<=n;i++)
    81         for(int j=1;j<=m;j++)
    82             ans+=bok[i][j];
    83     printf("%d
    ",ans);
    84 
    85     return 0;
    86 }
    View Code

    E. Nastya and Unexpected Guest(CF 1341E)

    一条路上从0-n,其中有m个安全点,他们分别是di。给出绿灯时间g红灯时间r

    1.在红灯时间上,不能走,且必须在安全点上面。

    2.在绿灯时间上,必须走

    3.除非到安全点才能够转弯,否则不能。

    4.每秒走1m,求到达n的最短时间。

    只有在路上完美的度过一个绿灯时间,并且最终点是安全点,才算答案。

    设f[i][j] 分别为 到达 d[i] 点时,绿灯时间过了 j 秒,最少的完整红绿灯时间个数。

    如果 j==0 且 n-d[i] <=g (当前绿灯时间没有,也就有几个完整的红绿灯时间,从d[i]点出发,能够直接到n点,也就是答案)

      ans=min(ans,f[i][j]*(g+r)+n-d[i]);  //完整的红绿灯个数*红绿灯时间 ,再加上最后一趟走的时间。

    如果 j==g //正好过了一个绿灯时间。也就是正好一个红绿灯轮回

      f[i][0]=f[i][j]+1 //个数加一,并且要把这个点放进队列尾端。

      que.push_back();

      continue;

    再从这个点 向左边的安全点 或者右边的安全点 走,转移一下,把这些状态都记录下来,其实是看 是否能走过一个完整的绿灯时间。

      f[p][v]=f[i][j]  //这时个数不加一,把这个点放进队列开头。

      que.push_front();

    最后输出答案就好了。 队列里最多有 m*g 个状态。且因为求最优,每个点只会经过一次。

     1 #include <iostream>
     2 #include <cstdio>
     3 #include <cmath>
     4 #include <algorithm>
     5 #include <set>
     6 #include <queue>
     7 #include <stack>
     8 #include <string>
     9 #include <cstring>
    10 #include <vector>
    11 #include <map>
    12 #include<ctime>
    13 //#include <unordered_map>
    14 #define mem( a ,x ) memset( a , x ,sizeof(a) )
    15 #define rep( i ,x ,y ) for( int i = x ; i<=y ;i++ )
    16 #define lson  l ,mid ,pos<<1
    17 #define rson mid+1 ,r ,pos<<1|1
    18 using namespace std;
    19 typedef long long ll ;
    20 typedef pair<int ,int> pii;
    21 typedef pair<ll ,int> pli;
    22 const int inf = 0x3f3f3f3f;
    23 const ll mod=998244353;
    24 const int N=10000+50;
    25 int n,m,d[N],g,r;
    26 int bok[N][1010],f[N][1010];
    27 ll ans=-1,res;
    28 struct node
    29 {
    30     int p,v;
    31 }e;
    32 void dfs()
    33 {
    34     deque<node>que;
    35     bok[0][0]=1;
    36     que.push_front({0,0});
    37     while(!que.empty())
    38     {
    39         e=que.front();  que.pop_front();
    40         if(e.v==0)
    41         {
    42             if(n-d[e.p]<=g)
    43             {
    44                 res=1ll*f[e.p][e.v]*(g+r)+n-d[e.p];
    45                 if(ans==-1||ans>res)
    46                     ans=res;
    47             }
    48         }
    49         if(e.v==g)
    50         {
    51             if(!bok[e.p][0])
    52             {
    53                 bok[e.p][0]=1;
    54                 f[e.p][0]=f[e.p][e.v]+1;
    55                 que.push_back({e.p,0});
    56             }
    57             continue;
    58         }
    59         if(e.p>1)
    60         {
    61             int p=e.p-1;
    62             int v=e.v+d[e.p]-d[p];
    63             if(v<=g&&!bok[p][v])
    64             {
    65                 bok[p][v]=1;
    66                 f[p][v]=f[e.p][e.v];
    67                 que.push_front({p,v});
    68             }
    69         }
    70         if(e.p<m)
    71         {
    72             int p=e.p+1;
    73             int v=e.v+d[p]-d[e.p];
    74             if(v<=g&&!bok[p][v])
    75             {
    76                 bok[p][v]=1;
    77                 f[p][v]=f[e.p][e.v];
    78                 que.push_front({p,v});
    79             }
    80         }
    81     }
    82     printf("%lld
    ",ans);
    83 }
    84 int main()
    85 {
    86     scanf("%d%d",&n,&m);
    87     for(int i=1;i<=m;i++)
    88         scanf("%d",&d[i]);
    89     sort(d+1,d+m+1);
    90     scanf("%d%d",&g,&r);
    91     dfs();
    92 
    93     return 0;
    94 }
    View Code

    Codeforces 590C Three States

  • 相关阅读:
    Android Jetpack之WorkManager: 观察结果
    解决'androidx.arch.core:core-runtime' has different version for the compile (2.0.0) and runtime (2.0.1)
    我要研究一下minio,管理大量的照片
    分发消息的写法
    百度地图坐标转换
    HighChart 实现从后台取数据来实时更新柱状和折线组图
    导出Excel
    Java 8新特性之集合
    java中的Switch case语句
    提问:"~"运算符
  • 原文地址:https://www.cnblogs.com/Kaike/p/12982042.html
Copyright © 2020-2023  润新知