CSES - Shared codeLink to this code:
https://cses.fi/paste/6e3a90c558efa6137bd8cc/
#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
using namespace __gnu_pbds;
using namespace std;
#define ordered_set tree<ll, null_type, less<ll>, rb_tree_tag, tree_order_statistics_node_update>
#define ll long long
#define ff first
#define ss second
#define pb push_back
#define endl '\n'
#define mp make_pair
#define mii map<ll, ll>
#define pii pair<ll, ll>
#define vi vector<ll>
#define vvi vector<vi>
#define vb vector<bool>
#define pii_pq_min
#define all(x) (x).begin(), (x).end()
#define endl '\n'
#define REP(i, a, b) for (ll i = a; i < b; i++)
#define MOD (ll)(1e9 + 7)
#define mod (ll)998244353
void fast()
{
ios_base::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
}
long long my_sqrt(long long a)
{
long long l=0,r=5000000001;
while(r-l>1)
{
long long mid=(l+r)/2;
if(1ll*mid*mid<=a)l=mid;
else r=mid;
}
return l;
}
bool cmps(pii &a, pii &b)
{
return a.ss < b.ss;
}
void solve()
{
ll n,m;cin>>n>>m;
// vector<pair<pii,ll>> edge(m);
vector<vector<pii>> adj(n+1);
REP(i,0,m)
{
ll u,v,w;cin>>u>>v>>w;
// edge.pb({{u,v},w});
adj[u].pb({v,w});
}
vi noDiscount(n+1,LONG_LONG_MAX);
vi discount(n+1,LONG_LONG_MAX);
discount[1] = 0;
noDiscount[1] = 0;
auto compare = [](const pair<ll, pair<ll, ll>>& a, const pair<ll, pair<ll, ll>>& b) {
return a.first > b.first; // Change to a.first < b.first for minimum priority
};
// Declare a priority queue with the custom comparison function
priority_queue<pair<ll, pair<ll, ll>>, vector<pair<ll, pair<ll, ll>>>, decltype(compare)> q(compare);
// priority_queue<pair<ll,pii> , vector<pair<ll,pii>>, greater<pii>> q;
q.push({0,{1,1}});
q.push({0,{1,0}});
vb discountVisited(n+1,false);
vb noDiscountVisited(n+1,false);
ll countDiscount = 0;
ll countNoDiscount = 0;
while(!q.empty())
{
ll prevDistance = q.top().ff;
ll isDiscounted = q.top().ss.ss;
ll u = q.top().ss.ff;
if(discountVisited[u] && noDiscountVisited[u]){
q.pop();
continue;
}
if(isDiscounted)
{
countDiscount++;
discountVisited[u] = 1;
}
else
{
noDiscountVisited[u] = 1;
countNoDiscount++ ;
}
for (auto x : adj[u])
{
if(isDiscounted)
{
if(prevDistance + x.ss < discount[x.ff])
{
discount[x.ff] = min<ll>(discount[x.ff] , prevDistance + x.ss);
q.push({discount[x.ff],{x.ff,1}}) ;
}
}
else
{
//current discounted
ll currentDiscounted = prevDistance + x.ss/2 ;
if(currentDiscounted < discount[x.ff])
{
discount[x.ff] = currentDiscounted ;
q.push({discount[x.ff],{x.ff,1}});
}
// no discount
ll currentCost = prevDistance + x.ss;
if(currentCost < noDiscount[x.ff])
{
noDiscount[x.ff] = currentCost;
q.push({noDiscount[x.ff],{x.ff,0}});
}
}
}
q.pop();
if(countNoDiscount == n && countDiscount == n)
break;
}
cout<<discount[n];
return;
}
int main()
{
fast();
// ll t;
// cin >> t;
// while (t--)
{
solve();
cout << endl;
}
return 0;
}