Submission #241396

#TimeUsernameProblemLanguageResultExecution timeMemory
241396kal013Olympic Bus (JOI20_ho_t4)C++17
0 / 100
182 ms160000 KiB
/*/ Author: kal013 /*/ // #pragma GCC optimize ("O3") #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<class T> using ordered_set = tree<T, null_type,less<T>, rb_tree_tag,tree_order_statistics_node_update> ; template<class key, class value, class cmp = std::less<key>> using ordered_map = tree<key, value, cmp, rb_tree_tag, tree_order_statistics_node_update>; // find_by_order(k) returns iterator to kth element starting from 0; // order_of_key(k) returns count of elements strictly smaller than k; template<class T> using min_heap = priority_queue<T, vector<T> , greater<T> >; struct custom_hash { // Credits: https://codeforces.com/blog/entry/62393 static uint64_t splitmix64(uint64_t x) { // http://xorshift.di.unimi.it/splitmix64.c x += 0x9e3779b97f4a7c15; x = (x ^ (x >> 30)) * 0xbf58476d1ce4e5b9; x = (x ^ (x >> 27)) * 0x94d049bb133111eb; return x ^ (x >> 31); } size_t operator()(uint64_t x) const { static const uint64_t FIXED_RANDOM = chrono::steady_clock::now().time_since_epoch().count(); return splitmix64(x + FIXED_RANDOM); } }; template<class T> ostream& operator<<(ostream &os, vector<T> V) { os << "[ "; for(auto v : V) os << v << " "; return os << "]"; } template<class T> ostream& operator<<(ostream &os, set<T> S){ os << "{ "; for(auto s:S) os<<s<<" "; return os<<"}"; } template<class T> ostream& operator<<(ostream &os, unordered_set<T> S){ os << "{ "; for(auto s:S) os<<s<<" "; return os<<"}"; } template<class T> ostream& operator<<(ostream &os, ordered_set<T> S){ os << "{ "; for(auto s:S) os<<s<<" "; return os<<"}"; } template<class L, class R> ostream& operator<<(ostream &os, pair<L,R> P) { return os << "(" << P.first << "," << P.second << ")"; } template<class L, class R> ostream& operator<<(ostream &os, map<L,R> M) { os << "{ "; for(auto m:M) os<<"("<<m.first<<":"<<m.second<<") "; return os<<"}"; } template<class L, class R> ostream& operator<<(ostream &os, unordered_map<L,R> M) { os << "{ "; for(auto m:M) os<<"("<<m.first<<":"<<m.second<<") "; return os<<"}"; } template<class L, class R, class chash = std::hash<R> > ostream& operator<<(ostream &os, gp_hash_table<L,R,chash> M) { os << "{ "; for(auto m:M) os<<"("<<m.first<<":"<<m.second<<") "; return os<<"}"; } #define TRACE #ifdef TRACE #define trace(...) __f(#__VA_ARGS__, __VA_ARGS__) template <typename Arg1> void __f(const char* name, Arg1&& arg1){ cerr << name << " : " << arg1 << endl; } template <typename Arg1, typename... Args> void __f(const char* names, Arg1&& arg1, Args&&... args){ const char* comma = strchr(names + 1, ','); cerr.write(names, comma - names) << " : " << arg1<<" | "; __f(comma+1, args...); } #else #define trace(...) 1 #endif mt19937_64 rng(chrono::steady_clock::now().time_since_epoch().count()); inline int64_t random_long(long long l,long long r){ uniform_int_distribution<int64_t> generator(l,r); return generator(rng); } inline int64_t random_long(){ uniform_int_distribution<int64_t> generator(LLONG_MIN,LLONG_MAX); return generator(rng); } /*/---------------------------Defines----------------------/*/ typedef vector<int> vi; typedef pair<int,int> pii; #define ll long long #define F first #define S second #define pb push_back #define endl "\n" #define all(v) (v).begin(),(v).end() /*/-----------------------Modular Arithmetic---------------/*/ const int mod=1e9+7; inline int add(int x,int y){ x+=y; if (x>=mod) return x-mod; return x; } inline int sub(int x,int y){ x-=y; if (x<0) return x+mod; return x; } inline int mul(int x,int y){ return (x*1ll*y)%mod; } inline int power(int x,int y){ int ans=1; while(y){ if (y&1) ans=mul(ans,x); x=mul(x,x); y>>=1; } return ans; } inline int inv(int x){ return power(x,mod-2); } /*/-----------------------------Code begins----------------------------------/*/ const int N = 205; const int M = 5e4+10; vector<int> adj[N][2]; const ll INF = 1e15+2; ll dist[N][N]; ll U[M][2], C[M],D[M]; ll dp[2][N][M][2]; void dijk(int idx,int src,int n,int m){ assert( idx == 0 || idx == 1); assert(src == 1 || src == n); int s_id = (src == 1) ? 0 : 1; vector<ll> dist(n+3,INF),par(n+3,-1); dist[src] = 0; min_heap<pair<ll,ll>> queue; queue.push({0,src}); while(!queue.empty()){ auto X = queue.top(); queue.pop(); if (X.first > dist[X.second]) continue; // assert(dist[X.second] == X.first); for(auto i: adj[X.second][idx]){ int v = U[i][0]^U[i][1]^X.second; if (dist[v] > dist[X.second] + C[i]){ dist[v] = dist[X.second] + C[i]; queue.push({dist[v],v}); par[v] = i; } } } vector<bool> vis(m+4,false); vector<int> used, unused; for(auto e: par){ if (e != -1) { assert(0 <= e && e < m); used.push_back(e); vis[e] = true; } } for(int i = 0; i<m ;++i){ if (!vis[i]){ unused.push_back(i); } } for(auto e: unused){ for(int z = 1; z <= n; ++z){ dp[idx][z][e][s_id] = dist[z]; } } assert(used.size() + unused.size() == m); vector<vector<int> > g(n+1); for(int i = 1; i <= n; ++i){ if (par[i] != -1){ assert(0 <= par[i] && par[i] < m); int u = U[par[i]][0]^U[par[i]][1]^i; g[u].push_back(i); } } for(auto e: used){ int u = U[e][0], v = U[e][1]; if (par[u] == e){ swap(u,v); } assert(par[v] == e); vector<ll> cur_dist(n+1,INF); cur_dist[src] = 0; // vector<int> bfs; // bfs.push_back(v); // for(int iter = 0 ; iter < bfs.size(); ++iter){ // int cu = bfs[iter]; // cur_dist[cu] = INF; // for(auto e:g[cu]){ // bfs.push_back(e); // assert(cur_dist[e] < INF); // } // } min_heap<pair<ll,ll> > cq; for(int i = 1; i<=n ;++ i){ if (cur_dist[i] < INF){ cq.push({cur_dist[i],i}); } } while(!cq.empty()){ auto X = cq.top(); cq.pop(); if (X.first > cur_dist[X.second]) continue; assert(cur_dist[X.second] == X.first); for(auto i: adj[X.second][idx]){ if (i == e) continue; int v = U[i][0]^U[i][1]^X.second; if (cur_dist[v] > cur_dist[X.second] + C[i]){ cur_dist[v] = cur_dist[X.second] + C[i]; cq.push({cur_dist[v],v}); } } } for(int z = 1; z <= n; ++z){ dp[idx][z][e][s_id] = cur_dist[z]; } } } void solve(){ int n,m; cin>>n>>m; assert( n < N && m < M); for(int i = 1; i<=n ; ++i){ for(int j = 1; j<=n ; ++j){ dist[i][j] = INF; } dist[i][i] = 0; } for(int i = 0; i < m; ++i){ cin>>U[i][0]>>U[i][1]>>C[i]>>D[i]; ll u = U[i][0], v = U[i][1]; assert(1 <= u && u <= n && 1 <= v && v <= n); dist[u][v] = min(dist[u][v], C[i]); adj[u][0].push_back(i); adj[v][1].push_back(i); } for(int mid = 1; mid <= n; ++mid){ for(int src = 1; src <= n; ++src){ for(int des = 1; des <= n ; ++des){ dist[src][des] = min(dist[src][mid] + dist[mid][des],dist[src][des]); } } } ll ans = min(INF, dist[1][n] + dist[n][1]); //dijk(0,1,n,m); //dijk(0,n,n,m); dijk(1,1,n,m); //dijk(1,n,n,m); // for(int i = 0; i < m; ++i){ // ll u = U[i][0], v = U[i][1]; // ll cur_s_t = dp[0][n][i][0]; // cur_s_t = min(cur_s_t, dp[0][v][i][0] + dp[1][u][i][1] + C[i]); // ll cur_t_s = dp[0][1][i][1]; // cur_t_s = min(cur_t_s, dp[0][v][i][1] + dp[1][u][i][0] + C[i]); // ans = min(ans, cur_t_s + cur_s_t + D[i]); // } if (ans >= INF){ ans = -1; } cout<<ans<<endl; } int main(){ // Use "set_name".max_load_factor(0.25);"set_name".reserve(512); with unordered set // Or use gp_hash_table<X,null_type> ios_base::sync_with_stdio(false);cin.tie(NULL);cout.tie(NULL); cout<<fixed<<setprecision(25); cerr<<fixed<<setprecision(10); auto start = std::chrono::high_resolution_clock::now(); int t=1; // cin>>t; while(t--) { solve(); } auto stop = std::chrono::high_resolution_clock::now(); auto duration = std::chrono::duration_cast<std::chrono::nanoseconds>(stop - start); // cerr << "Time taken : " << ((long double)duration.count())/((long double) 1e9) <<"s "<< endl; }

Compilation message (stderr)

In file included from /usr/include/c++/7/ext/pb_ds/detail/pat_trie_/pat_trie_.hpp:45:0,
                 from /usr/include/c++/7/ext/pb_ds/detail/container_base_dispatch.hpp:90,
                 from /usr/include/c++/7/ext/pb_ds/assoc_container.hpp:48,
                 from ho_t4.cpp:4:
ho_t4.cpp: In function 'void dijk(int, int, int, int)':
ho_t4.cpp:208:37: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
  assert(used.size() + unused.size() == m);
         ~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...