• 01bfs+最短路维护dp——cf1341E


    昨天刚刚做过类似的题,就是用最短路的松弛方式来维护dp数组

    /*
    考虑一个二元组(t,i)
    表示花费t时间,当前处在绿灯的now=t%g秒,处于结点i
        now!=0,可以扩展点(t+x,j),且now+x<=g
        now==0,可以扩展点(t+x,j),且x<=g
    y用一个优先队列维护这个二元组 
    */
    #include<bits/stdc++.h>
    using namespace std;
    #define ll long long 
    #define N 2000006
    
    int n,g,r,m,d[N],vis[10005][1005];
     
    int main(){
        cin>>n>>m;
        for(int i=1;i<=m;i++)scanf("%d",&d[i]);
        cin>>g>>r;
        
        priority_queue<pair<int,int> >pq;
        pq.push(make_pair(0,1));
        vis[1][0]=1;
        int tt=0;
        long long anss=1e16;
        while(pq.size()){
            ++tt;
            if(t>=5e6)break;
            pair<int,int> p=pq.front();pq.pop();
            int t=-p.first,u=p.second;
            if(u==m){
                long long ans=1ll*t/g*(g+r)+t%g;
                anss=min(anss,ans);
            }
            int now=t%g;
            for(int v=u+1;v<=m && now+d[v]-d[u]<=g;v++){
                if(!vis[v][now+d[v]-d[u]])vis[v][now+d[v]-d[u]]=1;
                else continue;
                pq.push(make_pair(-(t+d[v]-d[u]),v));        
            }
            for(int v=u-1;v>=1 && now+d[u]-d[v]<=g;v--){
                if(!vis[v][now+d[u]-d[v]])vis[v][now+d[u]-d[v]]=1;
                else continue;
                pq.push(make_pair(-(t+d[u]-d[v]),v));
            }
        }
        if(anss==1e16)puts("-1");
        else cout<<anss<<'
    ';
    }
    View Code

    当然这题时间卡的比较紧,我们还要优化掉dij的那个log

    所以采用01bfs,dis[i][j]表示到第i个点,已经到了绿灯j秒,经过的最少周期数

    #include<iostream>
    #include<cstdio>
    #include<string>
    #include<ctime>
    #include<cmath>
    #include<cstring>
    #include<algorithm>
    #include<stack>
    #include<climits>
    #include<queue>
    #include<map>
    #include<set>
    #include<sstream>
    #include<unordered_map>
    using namespace std;
     
    typedef long long LL;
     
    typedef unsigned long long ull;
     
    const int inf=0x3f3f3f3f;
     
    const int N=1e4+100;
     
    int n,m,r,g;
     
    bool vis[N][1010];
     
    int a[N],dis[N][1010];
     
    struct Node
    {
        int pos,step;
        Node(int pos,int step):pos(pos),step(step){}
    };
     
    int bfs()
    {
        int ans=-1;
        deque<Node>q;
        q.push_back(Node(0,0));
        vis[0][0]=true;
        while(q.size())
        {
            Node cur=q.front();
            q.pop_front();
            if(cur.step==0)//刚等完红灯
            {
                int remain=n-a[cur.pos];
                if(remain<=g)//如果能直接从这个安全岛冲到终点 
                {
                    LL temp=dis[cur.pos][cur.step]*(g+r)+remain;
                    if(ans==-1||temp<ans)
                        ans=temp;
                }
            }
            if(cur.step==g)//需要等红灯
            {
                if(!vis[cur.pos][0])
                {
                    dis[cur.pos][0]=dis[cur.pos][g]+1;
                    vis[cur.pos][0]=true;
                    q.push_back(Node(cur.pos,0));
                }
                continue;
            }
            if(cur.pos>1)//向前一格 
            {
                int pos=cur.pos-1;
                int step=cur.step+a[cur.pos]-a[pos];
                if(step<=g&&!vis[pos][step])
                {
                    dis[pos][step]=dis[cur.pos][cur.step];
                    vis[pos][step]=true;
                    q.push_front(Node(pos,step));
                }
            }
            if(cur.pos<m)//向后一格 
            {
                int pos=cur.pos+1;
                int step=cur.step+a[pos]-a[cur.pos];
                if(step<=g&&!vis[pos][step])
                {
                    dis[pos][step]=dis[cur.pos][cur.step];
                    vis[pos][step]=true;
                    q.push_front(Node(pos,step));
                }
            }
        }
        return ans;
    }
     
    int main()
    {
    
    //    ios::sync_with_stdio(false);
        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+1+m);
        printf("%d
    ",bfs());
    
     
        return 0;
    }
  • 相关阅读:
    函数
    向discuz里填充数据
    CI 基础
    FlashBuilder设置显示字符集
    win2003 Email邮件服务器搭配
    CI 模块化显示[仿照shopex功能]
    DW的鸟语
    CI 视图里加视图
    silverlight模拟单击事件
    自定义XML配置文件的操作类(转)
  • 原文地址:https://www.cnblogs.com/zsben991126/p/12814992.html
Copyright © 2020-2023  润新知