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\n",ans[i]);      
    return 0;
}

  

猜你喜欢

转载自www.cnblogs.com/guangheli/p/12375360.html
今日推荐