Submission #922445

#TimeUsernameProblemLanguageResultExecution timeMemory
922445GrindMachineOlympic Bus (JOI20_ho_t4)C++17
100 / 100
445 ms7972 KiB
#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>

using namespace std;
using namespace __gnu_pbds;

template<typename T> using Tree = tree<T, null_type, less<T>, rb_tree_tag, tree_order_statistics_node_update>;
typedef long long int ll;
typedef long double ld;
typedef pair<int,int> pii;
typedef pair<ll,ll> pll;

#define fastio ios_base::sync_with_stdio(false); cin.tie(NULL)
#define pb push_back
#define endl '\n'
#define sz(a) (int)a.size()
#define setbits(x) __builtin_popcountll(x)
#define ff first
#define ss second
#define conts continue
#define ceil2(x,y) ((x+y-1)/(y))
#define all(a) a.begin(), a.end()
#define rall(a) a.rbegin(), a.rend()
#define yes cout << "Yes" << endl
#define no cout << "No" << endl

#define rep(i,n) for(int i = 0; i < n; ++i)
#define rep1(i,n) for(int i = 1; i <= n; ++i)
#define rev(i,s,e) for(int i = s; i >= e; --i)
#define trav(i,a) for(auto &i : a)

template<typename T>
void amin(T &a, T b) {
    a = min(a,b);
}

template<typename T>
void amax(T &a, T b) {
    a = max(a,b);
}

#ifdef LOCAL
#include "debug.h"
#else
#define debug(x) 42
#endif

/*



*/

const int MOD = 1e9 + 7;
const int N = 200 + 5;
const int inf1 = int(1e9) + 5;
const ll inf2 = ll(1e18) + 5;
const int M = 5e4 + 5;

vector<array<ll,3>> adj[N];
vector<pll> adj2[N];
vector<bool> bridge(M);
vector<bool> vis(N);
vector<ll> tin(N), low(N);
ll timer = 1;

void dfs1(ll u, ll p){
    vis[u] = 1;
    tin[u] = low[u] = timer++;

    for(auto [v,id] : adj2[u]){
        if(v == p) conts;
        if(vis[v]){
            amin(low[u],tin[v]);
        }
        else{
            dfs1(v,u);
            amin(low[u],low[v]);
            if(low[v] > tin[u]){
                bridge[id] = 1;
            }
        }
    }
}

void dfs2(ll u, ll p, ll ignore){
    vis[u] = 1;
    for(auto [v,id] : adj2[u]){
        if(vis[v]) conts;
        if(id == ignore) conts;
        dfs2(v,u,ignore);
    }
}

vector<ll> topo;

void dfs3(ll u){
    vis[u] = 1;
    for(auto [v,id] : adj2[u]){
        if(vis[v]) conts;
        dfs3(v);
    }

    topo.pb(u);
}

void solve(int test_case)
{
    ll n,m; cin >> n >> m;
    vector<array<ll,4>> edges(m+5);

    rep1(i,m){
        ll u,v,w,d; cin >> u >> v >> w >> d;
        adj[u].pb({v,w,i}), adj[v].pb({u,w,i});
        edges[i] = {u,v,w,d};
    }

    auto dijkstra = [&](ll s, ll flipped){
        vector<ll> dis(n+5,inf2);
        dis[s] = 0;
        rep1(i,n) vis[i] = 0;

        rep1(iter,n){
            pll best = {inf2,inf2};
            rep1(u,n){
                if(vis[u]) conts;
                pll px = {dis[u],u};
                amin(best,px);
            }

            ll u = best.ss;
            vis[u] = 1;

            for(auto [v,w,id] : adj[u]){
                if(id != flipped){
                    if(edges[id][0] == u){
                        amin(dis[v],dis[u]+w);
                    }
                }
                else{
                    if(edges[id][0] == v){
                        amin(dis[v],dis[u]+w);
                    }
                }
            }
        }

        return dis;
    };

    auto dijkstra_rev = [&](ll s){
        vector<ll> dis(n+5,inf2);
        dis[s] = 0;
        rep1(i,n) vis[i] = 0;

        rep1(iter,n){
            pll best = {inf2,inf2};
            rep1(u,n){
                if(vis[u]) conts;
                pll px = {dis[u],u};
                amin(best,px);
            }

            ll u = best.ss;
            vis[u] = 1;

            for(auto [v,w,id] : adj[u]){
                if(edges[id][0] == v){
                    amin(dis[v],dis[u]+w);
                }
            }
        }

        return dis;
    };

    auto dis1 = dijkstra(1,-1);
    auto disn = dijkstra(n,-1);
    auto dis1_rev = dijkstra_rev(1);
    auto disn_rev = dijkstra_rev(n);

    rep1(u,n){
        for(auto [v,w,id] : adj[u]){
            if(edges[id][0] == u){
                if(dis1[u]+w == dis1[v]){
                    adj2[u].pb({v,id});
                }
            }
        }
    }

    auto go = [&](ll s){
        ll t = n^1^s;
        rep1(i,n) vis[i] = 0;
        topo.clear();
        dfs3(s);

        vector<ll> dp1(n+5), dp2(n+5);
        dp1[t] = 1;

        trav(u,topo){
            for(auto [v,id] : adj2[u]){
                dp1[u] += dp1[v];
                dp1[u] %= MOD;
            }
        }

        reverse(all(topo));
        vector<ll> inc[n+5];
        rep1(u,n){
            for(auto [v,id] : adj2[u]){
                inc[v].pb(u);
            }
        }

        dp2[s] = 1;

        trav(u,topo){
            trav(v,inc[u]){
                dp2[u] += dp2[v];
                dp2[u] %= MOD;
            }
        }

        rep1(u,n){
            for(auto [v,id] : adj2[u]){
                ll ways = dp1[v]*dp2[u]%MOD;
                if(ways == dp1[s]){
                    bridge[id] = 1;
                }
            }
        }
    };

    if(dis1[n] != inf2){
        go(1);
    }

    rep1(i,n) adj2[i].clear();

    rep1(u,n){
        for(auto [v,w,id] : adj[u]){
            if(edges[id][0] == u){
                if(disn[u]+w == disn[v]){
                    adj2[u].pb({v,id});
                }
            }
        }
    }

    timer = 1;
    fill(all(vis),0);
    if(disn[1] != inf2){
        go(n);
    }

    // assert(count(all(bridge),1) <= 2*n);
    // debug((ll)count(all(bridge),1));

    ll ans = inf2;
    amin(ans,dis1[n]+disn[1]);

    rep1(i,m){
        auto [u,v,w,d] = edges[i];
        if(bridge[i]){
            ll cost = d+dijkstra(1,i)[n]+dijkstra(n,i)[1];
            amin(ans,cost);
        }
        else{
            ll sp_1_n = min(dis1[n],dis1[v]+w+disn_rev[u]);
            ll sp_n_1 = min(disn[1],disn[v]+w+dis1_rev[u]);
            ll cost = d+sp_1_n+sp_n_1;
            amin(ans,cost);
            if(cost == 16){
                debug(i);
                debug(sp_1_n);
                debug(sp_n_1);
                debug(disn[1]);
            }
        }
    }

    if(ans == inf2) ans = -1;
    cout << ans << endl;
}

int main()
{
    fastio;

    int t = 1;
    // cin >> t;

    rep1(i, t) {
        solve(i);
    }

    return 0;
}

Compilation message (stderr)

ho_t4.cpp: In function 'void solve(int)':
ho_t4.cpp:46:18: warning: statement has no effect [-Wunused-value]
   46 | #define debug(x) 42
      |                  ^~
ho_t4.cpp:276:17: note: in expansion of macro 'debug'
  276 |                 debug(i);
      |                 ^~~~~
ho_t4.cpp:46:18: warning: statement has no effect [-Wunused-value]
   46 | #define debug(x) 42
      |                  ^~
ho_t4.cpp:277:17: note: in expansion of macro 'debug'
  277 |                 debug(sp_1_n);
      |                 ^~~~~
ho_t4.cpp:46:18: warning: statement has no effect [-Wunused-value]
   46 | #define debug(x) 42
      |                  ^~
ho_t4.cpp:278:17: note: in expansion of macro 'debug'
  278 |                 debug(sp_n_1);
      |                 ^~~~~
ho_t4.cpp:46:18: warning: statement has no effect [-Wunused-value]
   46 | #define debug(x) 42
      |                  ^~
ho_t4.cpp:279:17: note: in expansion of macro 'debug'
  279 |                 debug(disn[1]);
      |                 ^~~~~
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...