https://cses.fi/problemset/task/1195 to solve this problem i implemented dijkstra's and Dynamic Programming to decide whether to opt for coupon or not for each state transiton.But I'am getting TLE and not able to optimize my code. I think my approach is slow. Any suggestion please help. Here is william lin's code https://youtu.be/dZ_6MS14Mg4?t=13603 but i did't get his approach. If any one could explain what he did will be helpful
My Code
Here's my approach...
-Firstly find shortest path from 1 to every node. (answers in array A)
-Then find shortest path from N to every node (on Inverted graph) which means finding shortest path from every node to N.(answers in array B)
-Then consider each edge(u,v) in graph , suppose you are applying discount on that edge... then if we can reach 1 to u and N to v (in short v to N) then ans=min( ans , A[u] + weight/2 + B[v] )...
@Kartik_Bhanderi
Thanks for your input. I tried following your approach and wrote the following code:
However, I still seem to get TLE on the majority of test cases. Is this only because I've implemented Bellman-Ford instead of Dijkstra or would you refactor my current code to be more efficient?
Firstly put your code in spoiler properly. (for that choose spoiler and inside that choose block and place your code there...)
include include include include include include include include include using namespace std;
typedef long long ll; typedef unsigned long long ull; typedef vector vi; typedef vector vl; typedef vector vvi; typedef vector vvl; typedef vector<pair<int, int>> vpi; typedef vector<pair<long long, long long>> vpl; typedef pair<int, int> pi; typedef pair<long long, long long> pl;
define PB push_back define MP make_pair define REP(i, a, b) for (ll i = a; i <= (ll)b; i++) define REPR(i, a, b) for (ll i = a; i >= (ll)b; i--) define show(arr) \ cerr << #arr << " is:" \ << "\n[ "; \ for (auto& ax : arr) cout << ax << ", "; \ cout << "]\n\n"; define disp(x) cerr << #x << " is " << x << "\n"; define bm(x) cout << "!Here" << x << "!" \ << "\n"; define en "\n" define INF 1000000007 void solve();
int main() { ios::sync_with_stdio(false); cin.tie(nullptr); cout.tie(nullptr);
int testCases = 1; // cin >> testCases; while (testCases--) solve();
return 0; }
void solve() { ll n, m; cin >> n >> m;
vector<tuple<ll, ll, ll>> edges(m); for (auto& [a, b, w] : edges) cin >> a >> b >> w;
vl distFrom1(n + 1, INF), distFromN(n + 1, INF); distFrom1[1] = distFromN[n] = 0;
REP(i, 0, n — 1) { for (auto [a, b, w] : edges) { distFrom1[b] = min(distFrom1[b], distFrom1[a] + w); distFromN[a] = min(distFromN[a], distFromN[b] + w); } }
ll ans = INF; for (auto [a, b, w] : edges) ans = min(ans, distFrom1[a] + (w / 2) + distFromN[b]);
cout << ans << en; }
And as you said you have implemented bellmen ford , whose time complexity is O(V.E) , so obviously it will result into TLE.
And in our case we only need single source shortest path , hence no need to use bellman ford instead we can use dijkstra's algo.
Hope it helps ;)
Sorry about that; I've fixed the formatting now.
And yes, I thought so too. Thanks for the confirmation. I'll try to learn Dijkstra's and implement it now!
Good.
Hi Kartik_Bhanderi I got TLE in 4 cases by using Dijkstra too!
Can you please check if anything went wrong?
Why do you put the array (node,distance) in the priority queue, shouldn't it be the other way around to correctly sort distance first? I think that could be your problem.
long long
only when it's neededYour logic also seems to be wrong, in priority queue it shoud be
(dist,node)
.Sir, can you please explain what is 'u' and what is 'v'?
Both represent Node.
From answer's context : there is an edge between node u and node v.
I got same aproach as yours, but use priority_queue instead of set. And I do not erase any extra element from the queue at any time. Just put new vertex on the queue whenever one of the dp-values becomes smaller.
By adding negative values of DP you are priority queue work as min_heap?
Yes, this is just to make the priority_queue.top() work like set.begin(), ie return the smallest element.
Is it safe to assume that set operations are more expensive than operations on priority queue?
Yes, of course, especially write access is more expensive. Same O(logn), but bigger constant factor.