zoukankan      html  css  js  c++  java
  • BZOJ 4239: 巴士走读 最短路

    显然,我们可以将询问按照规定时间从小到大排序,依次处理.       

    那么我们显然要求合法的点中从 $n$ 号点出发到达点 $i$ 的最迟时间,我们令这个为 $f[i]$ 

    而 $f[i]$ 显然可以用最短路来求. 

    如果求 $n$ 次最短路的话显然超时,但是我们可以对于每一个节点所连边排序,然后每次枚举之前没有扩展过的边. 

    这样就能保证每条边恰好被扩展一次,时间复杂度正确. 

    code: 

    #include <bits/stdc++.h> 
    #define N 200004  
    #define inf 1000000004   
    #define setIO(s) freopen(s".in","r",stdin) 
    using namespace std;    
    int cur,n,m;     
    int f[N],done[N],tag[N],ans[N];        
    struct Node {
        int u,dis; 
        Node(int u=0,int dis=0):u(u),dis(dis){} 
        bool operator<(Node b) const { return b.dis>dis; }               
    };     
    struct ask {
        int id,tim;    
        ask(int id=0,int tim=0):id(id),tim(tim){}  
    }as[N];     
    struct edge {   
        int to,st,ed;   
        edge(int to=0,int st=0,int ed=0):to(to),st(st),ed(ed){}  
    };  
    bool cmp_as(ask a,ask b) {
        return a.tim<b.tim;  
    }
    bool cmp(edge a,edge b) {
        return a.ed<b.ed;   
    }
    vector<edge>G[N];  
    priority_queue<Node>q;   
    void dij() {
        while(!q.empty()) {     
            Node e=q.top(); q.pop();      
            int u=e.u;   
            if(done[u]==cur) continue;   
            done[u]=cur;         
            for(int i=tag[u];i<G[u].size();++i,++tag[u]) {
                if(G[u][i].ed>f[u]) break;    
                int v=G[u][i].to;    
                if(f[v]<G[u][i].st) {
                    f[v]=G[u][i].st;     
                    q.push(Node(v,f[v]));   
                }    
            }
        }
    }
    void solve(int t) {   
        f[n]=t;     
        q.push(Node(n,f[n]));    
        dij();   
    }    
    int main() { 
        // setIO("input");  
        int i,j;        
        scanf("%d%d",&n,&m);    
        for(i=1;i<=m;++i) {
            int a,b,x,y;  
            scanf("%d%d%d%d",&a,&b,&x,&y);        
            G[b].push_back(edge(a,x,y));            
        }          
        memset(f,-1,sizeof(f));   
        f[n]=0;     
        for(i=1;i<=n;++i)  {
            sort(G[i].begin(),G[i].end(),cmp);    
        }
        int Q; 
        scanf("%d",&Q);    
        for(i=1;i<=Q;++i) {
            as[i].id=i; 
            scanf("%d",&as[i].tim);   
        } 
        sort(as+1,as+1+Q,cmp_as);      
        for(i=1;i<=Q;++i) {
            cur=i;  
            solve(as[i].tim);     
            ans[as[i].id]=f[1];   
        }
        for(i=1;i<=Q;++i) 
            printf("%d
    ",ans[i]);      
        return 0;
    }
    

      

  • 相关阅读:
    print 带颜色打印
    bootstrap-duallistbox使用
    Linux 查看和更改系统字符集
    nginx 不重装实现动态添加模块
    ubuntu 安装openssh-server出现依赖关系解决
    linux安装和使用zookeeper
    网页背景蜘蛛丝特效
    RabbitMQ与SpringBoot整合
    Redis常用命令
    设计模式(Design Patterns)
  • 原文地址:https://www.cnblogs.com/guangheli/p/12375360.html
Copyright © 2011-2022 走看看