Submission #681773

#TimeUsernameProblemLanguageResultExecution timeMemory
681773kymRobot (JOI21_ho_t4)C++14
34 / 100
3103 ms126500 KiB
#include <bits/stdc++.h> using namespace std; #define int long long #define FOR(i,s,e) for(int i = s; i <= (int)e; ++i) #define DEC(i,s,e) for(int i = s; i >= (int)e; --i) #define IAMSPEED ios_base::sync_with_stdio(false); cin.tie(0); #ifdef LOCAL #define db(x) cerr << #x << "=" << x << "\n" #define db2(x, y) cerr << #x << "=" << x << " , " << #y << "=" << y << "\n" #define db3(a,b,c) cerr<<#a<<"="<<a<<","<<#b<<"="<<b<<","<<#c<<"="<<c<<"\n" #define dbv(v) cerr << #v << ":"; for (auto ite : v) cerr << ite << ' '; cerr <<"\n" #define dbvp(v) cerr << #v << ":"; for (auto ite : v) cerr << "{" << ite.f << ',' << ite.s << "} "; cerr << "\n" #define dba(a,ss,ee) cerr << #a << ":"; FOR(ite,ss,ee) cerr << a[ite] << ' '; cerr << "\n" #define reach cerr << "LINE: " << __LINE__ << "\n"; #else #define reach #define db(x) #define db2(x,y) #define db3(a,b,c) #define dbv(v) #define dbvp(v) #define dba(a,ss,ee) #endif mt19937 rng(chrono::steady_clock::now().time_since_epoch().count()); #define pb push_back #define eb emplace_back #define all(x) (x).begin(), (x).end() #define f first #define s second #define g0(x) get<0>(x) #define g1(x) get<1>(x) #define g2(x) get<2>(x) #define g3(x) get<3>(x) typedef pair <int, int> pi; typedef tuple<int,int,int> ti3; typedef tuple<int,int,int,int> ti4; int rand(int a, int b) { return a + rng() % (b-a+1); } const int MOD = 1e9 + 7; const int inf = (int)1e9 + 500; const long long oo = (long long)1e18 + 500; template <typename T> bool chmax(T& a, const T b) { return a<b ? a = b, 1 : 0; } template <typename T> bool chmin(T& a, const T b) { return a>b ? a = b, 1 : 0; } const int MAXN = 200005; int n,m; struct edge{ int a,b,c,p; }; edge E[MAXN]; vector<pi> V[MAXN]; map<int,int> dist[MAXN][2]; map<int,vector<pi>> T[MAXN]; map<int,int> S[MAXN]; struct state { int node; bool a;// should this be the one left?? int color; // what colour is the edge that came in? bool operator<(const state& o) const { return node < o.node; } }; typedef pair<int,state> pis ; int32_t main() { IAMSPEED cin >> n >> m; FOR(i,1,m) { cin >> E[i].a >> E[i].b >> E[i].c >> E[i].p; V[E[i].a].pb({E[i].b,i}); V[E[i].b].pb({E[i].a,i}); } FOR(i,1,n) { for(auto v:V[i]){ S[i][E[v.s].c]+=E[v.s].p; T[i][E[v.s].c].pb(v); } } std::priority_queue<pis,vector<pis>,greater<pis>> pq; dist[1][0][0]=0; dist[1][1][0]=0; pq.push(make_pair(0, state({1, 0, 0}))); pq.push(make_pair(0, state({1, 1, 0}))); while(pq.size()) { // color is jsut the color you CAME INTO THE NODE with pis c=pq.top(); pq.pop(); state ss=c.s; int d=c.f; int node=ss.node, z=ss.a; int color=ss.color; if(dist[node][z][color] != d)continue; if(z){ if(T[node][color].size()<=1)continue; for(auto v:T[node][color]){ // adj list of this color if(v.f == node)continue; int sum=S[node][E[v.s].c]; // take everything int nx=v.f; int nd=d + sum - E[v.s].p; // sum - Px (-Pparent is already done at previous node) auto it=dist[nx][0].find(color); if(it == dist[nx][0].end() || it->s>nd) { if(it!=dist[nx][0].end())it->s=nd; else dist[nx][0][color]=nd; pq.push(make_pair(nd, state({nx, 0, color}))); // don't make the other node choose everything } } } else { for(auto v:V[node]) { int nx=v.f; int nd=d; int thiscolor=E[v.s].c; bool changed=0; if(T[node][thiscolor].size()>1) { nd += E[v.s].p; changed=1; } auto it1=dist[nx][0].find(thiscolor); if(it1 == dist[nx][0].end() || it1->s>min(nd, d + S[node][E[v.s].c] - E[v.s].p)) { if(it1!=dist[nx][0].end()) it1->s=min(nd, d + S[node][E[v.s].c] - E[v.s].p); else dist[nx][0][thiscolor]=min(nd, d + S[node][E[v.s].c] - E[v.s].p); pq.push(make_pair(min(nd, d + S[node][E[v.s].c] - E[v.s].p), state({nx, 0, thiscolor}))); // don't make the other node choose everything } if(changed){ auto it2=dist[nx][1].find(thiscolor); if(it2 == dist[nx][1].end() || it2->s>nd-E[v.s].p) { if(it2!=dist[nx][1].end())it2->s=nd-E[v.s].p; else dist[nx][1][thiscolor]=nd-E[v.s].p; pq.push(make_pair(nd-E[v.s].p, state({nx, 1, thiscolor})));//yes you must choose everything to get this compensation } } } } } int ans = oo; for(auto i:dist[n][0]) { chmin(ans, i.s); } if(ans==oo)cout<<-1; else cout << ans; }
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...