Submission #1268758

#TimeUsernameProblemLanguageResultExecution timeMemory
1268758YassirSalamaOlympic Bus (JOI20_ho_t4)C++20
5 / 100
887 ms12280 KiB
#pragma GCC optimize("Ofast,no-stack-protector") #include <bits/stdc++.h> #define int long long using namespace std; #define endl "\n" using ull=unsigned long long; using pii=pair<int,int>; const int dx[4] = {-1,0,1,0}, dy[4] = {0,1,0,-1}; #define OVL(x,s) for(auto y:x) cout<<y<<s; cout<<"\n"; template <typename T> istream& operator>>(istream& is, vector<T> &a) { copy_n(istream_iterator<T>(is), a.size(), a.begin()); return is;} #ifdef IOI template<typename A, typename B> ostream& operator<<(ostream &os, const pair<A, B> &p) { return os << '(' << p.first << ", " << p.second << ')'; } template<typename T_container, typename T = typename enable_if<!is_same<T_container, string>::value, typename T_container::value_type>::type> ostream& operator<<(ostream &os, const T_container &v) { os << '{'; string sep; for (const T &x : v) os << sep << x, sep = ", "; return os << '}'; } void dbg_out() { cout << endl; } template<typename Head, typename... Tail> void dbg_out(Head H, Tail... T) { cout << ' ' << H; dbg_out(T...); } #define dbg(...) cout << "(" << #__VA_ARGS__ << "):", dbg_out(__VA_ARGS__); #else #define dbg(...) 1337; #endif #define pb push_back #define F first #define S second #define all(v) v.begin(),v.end() const int maxn = 200+100; const int mod = 1e9+7; template < int MOD = 1000000007, typename T = int > struct ModInt { T val; ModInt(T V = 0) : val(V) { val %= MOD; } ModInt& operator += (const ModInt& rhs) { if ((val += rhs.val) >= MOD) val -= MOD; return *this; } ModInt& operator += (const T rhs) { if ((val += rhs) >= MOD) val -= MOD; return *this; } ModInt& operator -= (const ModInt& rhs) { if ((val += MOD - rhs.val) >= MOD) val -= MOD; return *this; } ModInt& operator -= (const T rhs) { if ((val += MOD - rhs) >= MOD) val -= MOD; return *this; } ModInt& operator *= (const ModInt& rhs) { val = (1ll * val * rhs.val) % MOD; return *this; } ModInt& operator *= (const T rhs) { val = (1ll * val * rhs) % MOD; return *this; } ModInt& operator /= (const ModInt& rhs) { return *this *= rhs.inverse(); } ModInt& operator /= (const T rhs) { return *this *= ModInt(rhs).inverse(); } ModInt& operator %= (const ModInt& rhs) { val %= rhs.val; return *this; } ModInt& operator %= (const T rhs) { val %= rhs; return *this; } ModInt& operator ++() { return *this += 1; } ModInt& operator --() { return *this -= 1; } ModInt operator + (const ModInt& rhs) const { ModInt res(*this); return res += rhs; } ModInt operator + (const T rhs) const { ModInt res(*this); return res += rhs; } ModInt operator % (const ModInt& rhs) const { ModInt res(*this); return res %= rhs; } ModInt operator % (const T rhs) const { ModInt res(*this); return res %= rhs; } ModInt operator - (const ModInt& rhs) const { ModInt res(*this); return res -= rhs; } ModInt operator - (const T rhs) const { ModInt res(*this); return res -= rhs; } ModInt operator * (const ModInt& rhs) const { ModInt res(*this); return res *= rhs; } ModInt operator * (const T rhs) const { ModInt res(*this); return res *= rhs; } ModInt operator / (const ModInt& rhs) const { ModInt res(*this); return res /= rhs; } ModInt operator / (const T rhs) const { ModInt res(*this); return res /= rhs; } ModInt& operator = (const ModInt& rhs) { val = rhs.val; return *this; } ModInt& operator = (const T rhs) { val = rhs; return *this; } T operator ~ () { return ~val; } bool operator ! () { return !val; } bool operator == (const ModInt& rhs) const { return val == rhs.val; } bool operator == (const T rhs) const { return val == rhs; } bool operator != (const ModInt& rhs) const { return val != rhs.val; } bool operator != (const T rhs) const { return val != rhs; } bool operator < (const ModInt& rhs) const { return val < rhs.val; } bool operator < (const T rhs) const { return val < rhs; } bool operator <= (const ModInt& rhs) const { return val <= rhs.val; } bool operator <= (const T rhs) const { return val <= rhs; } bool operator > (const ModInt& rhs) const { return val > rhs.val; } bool operator > (const T rhs) const { return val > rhs; } bool operator >= (const ModInt& rhs) const { return val >= rhs.val; } bool operator >= (const T rhs) const { return val >= rhs; } T operator () () const { return val; } ModInt inverse() const { return power(MOD - 2); } ModInt power(T n) const { ModInt a = *this, res = 1; while (n > 0) { if (n & 1) res *= a; a *= a, n >>= 1; } return res; } ModInt power(ModInt n) const { ModInt a = *this, res = 1; T e = n(); while (e > 0) { if (e & 1) res *= a; a *= a, e >>= 1; } return res; } friend ModInt operator ^ (ModInt rhs, T n) { return rhs.power(n); } friend ModInt operator ^ (ModInt rhs, ModInt n) { return rhs.power(n); } friend std::istream& operator>>(std::istream& is, ModInt& x) noexcept { return is >> x.val; } friend std::ostream& operator<<(std::ostream& os, const ModInt& x) noexcept { return os << x.val; } }; using mint = ModInt < (int)1e9+7 >; int n,m; set<pair<int,int>> v[maxn]; set<vector<int>> inc[maxn]; int b = 0; vector<int> dij(int src){ vector<int> dist(n+1,1e18); dist[src] = 0; priority_queue<pair<int,int>> q; q.push({0,src}); bool visited[n+1]; memset(visited,false,sizeof(visited)); while(!q.empty()){ auto [t,node] = q.top(); q.pop(); if(visited[node] == 1) continue; visited[node] = 1; for(auto [x,w] : v[node]){ if(x==b) continue; if(visited[x]) continue; if(dist[x]>dist[node]+w){ dist[x] = dist[node]+w; q.push({-dist[x],x}); } } } return dist; } set<pair<int,int>> g[maxn]; vector<int> rdij(int src){ vector<int> dist(n+1,1e18); dist[src] = 0; priority_queue<pair<int,int>> q; q.push({0,src}); bool visited[n+1]; memset(visited,false,sizeof(visited)); while(!q.empty()){ auto [t,node] = q.top(); q.pop(); if(visited[node] == 1) continue; visited[node] = 1; for(auto [x,w] : g[node]){ if(x==b) continue; if(visited[x]) continue; if(dist[x]>dist[node]+w){ dist[x] = dist[node]+w; q.push({-dist[x],x}); } } } return dist; } signed main() { ios_base::sync_with_stdio(0); cin.tie(0); cin>>n>>m; vector<vector<int>> edges; for(int i = 0;i<m;i++){ int a,b,c,d; cin>>a>>b>>c>>d; edges.pb({a,b,c,d}); v[a].insert({b,c}); g[b].insert({a,c}); inc[b].insert({a,c,d}); } int ans = 1e18; b = 0; ans = min(ans,dij(1)[n]+dij(n)[1]); dbg(ans,dij(1),dij(n)) for(int i=1;i<=n;i++){ b = i; vector<int> d1 = dij(1); vector<int> dn = dij(n); vector<int> rd1 = rdij(1); vector<int> rdn = rdij(n); //suppose we do it for incoming edges going from 1 to n //imagine we reverse edge a->i vector<pair<int,int>> a; set<pair<int,int>> s; //dp[1][i] can't be calculated, so it's min over all other nodes //dp[n][i] can't be calculated too, so it's min over all other nodes set<vector<int>> s1,s2; //s1 contains d1[a]+cost //s2 contains dn[a] for(auto x : inc[i]){ int node = x[0]; int c = x[1]; s1.insert({d1[node]+c,node}); s2.insert({dn[node]+c,node}); } //imagine we go from 1 to node to i //cost = d1[i]+c+rdn[node]+dn[1]+d //cost2 = d1[n]+dn[i]+c+rd1[node]+d //cost3 = (d1[i]+c+rdn[node])+(dn[i]+c+rd1[node])+d for(auto x : inc[i]){ int node = x[0]; int c = x[1]; int d = x[2]; s1.erase({d1[node]+c,node}); s2.erase({dn[node]+c,node}); if(s1.empty()||s2.empty()){ break; } if(i!=1) d1[i] = (*s1.begin())[0]; if(i!=n) dn[i] = (*s2.begin())[0]; int cost = d1[i]+c+rdn[node]+dn[1]+d; ans = min(ans,cost); cost = d1[n]+dn[i]+c+rd1[node]+d; ans = min(ans,cost); cost = (d1[i]+c+rdn[node])+(dn[i]+c+rd1[node])+d; ans = min(ans,cost); s1.insert({d1[node]+c,node}); s2.insert({dn[node]+c,node}); } } if(ans==1e18) ans = -1; cout<<ans<<endl; }
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...