제출 #1013192

#제출 시각아이디문제언어결과실행 시간메모리
1013192UnforgettableplEscape Route (JOI21_escape_route)C++17
100 / 100
3806 ms230648 KiB
#include "escape_route.h"
#include <bits/stdc++.h>
using namespace std;

#define int long long

const int INF = 1e18;

std::vector<long long> calculate_necessary_time(
    int32_t N, int32_t M, long long S, int32_t Q, std::vector<int32_t> A, std::vector<int32_t> B,
    std::vector<long long> L, std::vector<long long> C, std::vector<int32_t> U,
    std::vector<int32_t> V, std::vector<long long> T) {
    vector<vector<tuple<int,int,int>>> adj(N);
    vector<vector<tuple<int,int,int,int>>> sadj(N);
    map<pair<int,int>,int> lookup;
    for(int i=0;i<M;i++){
        lookup[{A[i],B[i]}]=i;
        lookup[{B[i],A[i]}]=i;
        adj[A[i]].emplace_back(B[i],L[i],C[i]);
        adj[B[i]].emplace_back(A[i],L[i],C[i]);
        sadj[A[i]].emplace_back(C[i]-L[i],B[i],L[i],i);
        sadj[B[i]].emplace_back(C[i]-L[i],A[i],L[i],i+M);
    }
    for(int i=0;i<N;i++)sort(sadj[i].rbegin(),sadj[i].rend());
    vector<vector<int>> distances(N,vector<int>(N));
    for(int i=0;i<N;i++){
        priority_queue<pair<int,int>> q;
        q.emplace(0,i);
        vector<int> visited(N,1e18);
        vector<bool> vis(N);
        visited[i] = 0;
        while(!q.empty()){
            auto [dist,idx] = q.top();q.pop();dist=-dist;
            if(vis[idx])continue;
            vis[idx]=true;
            for(auto[v,l,c]:adj[idx])if(!vis[v]){
                int nxttime = 0;
                int currtime = dist%S;
                if(currtime<=c-l)nxttime=dist+l;
                else {
                    nxttime = (dist/S)*S+l+S;
                }
                if(nxttime<visited[v]){
                    visited[v]=nxttime;
                    q.emplace(-nxttime,v);
                }
            }
        }
        distances[i]=visited;
    }
    vector<int> ans(Q);
    vector<vector<tuple<int,int,int>>> queries(N);
    for(int i=0;i<Q;i++)queries[U[i]].emplace_back(T[i],i,V[i]);
    for(int i=0;i<N;i++)sort(queries[i].rbegin(),queries[i].rend());
    vector<vector<int>> distancesviaedge(2*M);
    for(int i=0;i<M;i++){
        // Say we depart from A[i] for x=i and B[i] for x=i+m at C[i]-L[i]
        vector<bool> vis(N);
        vector<int> disti(N,INF);
        priority_queue<pair<int,int>> q;
        q.emplace(-(C[i]-L[i]),A[i]);
        while(!q.empty()){
            auto [dist,idx] = q.top();q.pop();dist=-dist;
            if(vis[idx])continue;
            vis[idx]=true;
            disti[idx] = dist-(C[i]-L[i]);
            for(auto[v,l,c]:adj[idx])if(dist<=c-l and !vis[v])q.emplace(-dist-l,v);
        }
        distancesviaedge[i]=disti;
    }
    for(int i=0;i<M;i++){
        // Say we depart from A[i] for x=i and B[i] for x=i+m at C[i]-L[i]
        vector<bool> vis(N);
        vector<int> disti(N,INF);
        priority_queue<pair<int,int>> q;
        q.emplace(-(C[i]-L[i]),B[i]);
        while(!q.empty()){
            auto [dist,idx] = q.top();q.pop();dist=-dist;
            if(vis[idx])continue;
            vis[idx]=true;
            disti[idx] = dist-(C[i]-L[i]);
            for(auto[v,l,c]:adj[idx])if(dist<=c-l and !vis[v])q.emplace(-dist-l,v);
        }
        distancesviaedge[i+M]=disti;
    }
    for(int i=0;i<N;i++){
        set<pair<int,int>> edges;
        vector<int> dist(N,INF);
        vector<int> addedidx(N);
        auto update_node = [&](int x,int newd){
            if(newd>=dist[x])return;
            if(dist[x]>=INF){
                // First time adding
                edges.insert(make_pair(get<0>(sadj[x][0])-newd,get<3>(sadj[x][0])));
            } else if(addedidx[x]!=sadj[x].size()) {
                edges.erase(make_pair(get<0>(sadj[x][addedidx[x]])-dist[x],get<3>(sadj[x][addedidx[x]])));
                edges.insert(make_pair(get<0>(sadj[x][addedidx[x]])-newd,get<3>(sadj[x][addedidx[x]])));
            }
            dist[x]=newd;
        };
        auto update_edge = [&](int e){
            int v = -1;
            if(e>=M)v=B[e-M];
            else v=A[e];
            edges.erase(make_pair(get<0>(sadj[v][addedidx[v]])-dist[v],get<3>(sadj[v][addedidx[v]])));
            addedidx[v]++;
            if(addedidx[v]!=sadj[v].size())edges.insert(make_pair(get<0>(sadj[v][addedidx[v]])-dist[v],get<3>(sadj[v][addedidx[v]])));
            for(int x=0;x<N;x++)update_node(x,dist[v]+distancesviaedge[e][x]);
        };
        update_node(i,0);
        for(auto[tim,idx,dest]:queries[i]){
            while(!edges.empty() and (--edges.end())->first>=tim)update_edge((--edges.end())->second);
            ans[idx] = dist[dest];
            for(int j=0;j<N;j++){
                if(dist[j]>=INF)continue;
                ans[idx] = min(ans[idx],distances[j][dest]+S-tim);
            }
        }
    }
    return ans;
}

컴파일 시 표준 에러 (stderr) 메시지

escape_route.cpp: In lambda function:
escape_route.cpp:95:34: warning: comparison of integer expressions of different signedness: '__gnu_cxx::__alloc_traits<std::allocator<long long int>, long long int>::value_type' {aka 'long long int'} and 'std::vector<std::tuple<long long int, long long int, long long int, long long int> >::size_type' {aka 'long unsigned int'} [-Wsign-compare]
   95 |             } else if(addedidx[x]!=sadj[x].size()) {
escape_route.cpp: In lambda function:
escape_route.cpp:107:27: warning: comparison of integer expressions of different signedness: '__gnu_cxx::__alloc_traits<std::allocator<long long int>, long long int>::value_type' {aka 'long long int'} and 'std::vector<std::tuple<long long int, long long int, long long int, long long int> >::size_type' {aka 'long unsigned int'} [-Wsign-compare]
  107 |             if(addedidx[v]!=sadj[v].size())edges.insert(make_pair(get<0>(sadj[v][addedidx[v]])-dist[v],get<3>(sadj[v][addedidx[v]])));
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...