|
| 1 | +//This algorithm does the same thing as bellman ford and has the same time complexity but is constant time faster |
| 2 | +//look idk how to do all he fancy struct stuff. so dont complain or just use the bellman ford |
| 3 | +#include <bits/stdc++.h> |
| 4 | +using namespace std; |
| 5 | +typedef pair<int,int> ii; |
| 6 | +queue<int> q; |
| 7 | +const int N=10003; // put number of nodes+3 here PLS CHANGE THIS ACCORDINGLY |
| 8 | +int w[N],c2[N];//w is shortest path to a node, c2 is number of time a node has been relaxed |
| 9 | +bool c[N];//c is to check whether a certain node is in the queue |
| 10 | +vector<ii> data [N]; //adjacency list of graph |
| 11 | +void edge(int x,int y, int l){ //there is a directed edge from x to y with length l |
| 12 | + data[x].push_back(ii (y,l)); |
| 13 | +} |
| 14 | +void initialize(){//initialize variables, may not be the fastest |
| 15 | + memset(c2,0,sizeof(c2)); //i apologize for using memset |
| 16 | + memset(c,true,sizeof(c)); |
| 17 | + memset(w,63,sizeof(w)); //depends on largest path from 1 node to another IMPORTANT |
| 18 | + for (int x=0;x<N;x++){ |
| 19 | + data[x].clear(); |
| 20 | + } //note that the algorithm until the queue is empty so there is no need to initialize queue |
| 21 | +} |
| 22 | +void setup(int s){//s is the source node |
| 23 | + q.push(s); |
| 24 | + w[s]=0; |
| 25 | +} |
| 26 | +void bfs(int x){ //this is no mark everything under the negative weight cycle as inf length |
| 27 | + int l=data[x].size(),a; |
| 28 | + for (int y=0;y<l;y++){ //for each of x neighbour |
| 29 | + a=data[x][y].first; |
| 30 | + if (c2[a]<N){ // if neighbour is not marked as -INF length |
| 31 | + c2[a]=N; //mark it as such |
| 32 | + bfs(a); //mark all its neighbours as such |
| 33 | + } |
| 34 | + } |
| 35 | +} |
| 36 | +void SPFA(){ |
| 37 | + int n,l,u,d; |
| 38 | + while (!q.empty()){ |
| 39 | + n=q.front(); // n is node to relax neighbours |
| 40 | + q.pop(); |
| 41 | + if (c2[n]>=N) continue; // if n is part of negative weight cycle, ignore |
| 42 | + c[n]=true; //mark n is not in queue |
| 43 | + l=data[n].size(); //just for constant time improvement |
| 44 | + for (int x=0;x<l;x++){ |
| 45 | + u=data[n][x].first; |
| 46 | + d=data[n][x].second; |
| 47 | + if (w[u]>w[n]+d){ // if u can be relaxed |
| 48 | + w[u]=w[n]+d; //relaxing u |
| 49 | + c2[u]++;// count number of time u has been relaxed. as u can only be relaxed N-1 times if its not in negative weight cycle |
| 50 | + if (c2[u]==N){ //if n in is negative wieght cycle |
| 51 | + bfs(u); //mark all of u neighbours as - INF weight |
| 52 | + } |
| 53 | + else if (c[u]){ //if u is not in queue |
| 54 | + c[u]=false; //mark u is in queue |
| 55 | + q.push(u); //push u into queue |
| 56 | + } |
| 57 | + } |
| 58 | + } |
| 59 | + } |
| 60 | +} |
| 61 | +void print(int n){ // print length of shortest path |
| 62 | + if (c2[n]>=N){ |
| 63 | + printf("-Infinity\n"); //part of negative wieght cycle |
| 64 | + } |
| 65 | + else if (w[n]==1061109567){ |
| 66 | + printf("Impossible\n"); //unreachable form source node |
| 67 | + } |
| 68 | + else{ |
| 69 | + printf("%d\n",w[n]); //else just print its shortest path |
| 70 | + } |
| 71 | +} |
| 72 | +int main(){ // the example graph has 5 nodes and 4 edges |
| 73 | + initialize(); //pls initialize or weird stuff might happen |
| 74 | + edge(0,1,999); |
| 75 | + edge (1,2,-2); |
| 76 | + edge(2,1,1); |
| 77 | + edge (0,3,2); |
| 78 | + setup(0); //0 is source node |
| 79 | + SPFA(); |
| 80 | + print(1); |
| 81 | + print(3); |
| 82 | + print(4); |
| 83 | + return 0; |
| 84 | +} |
0 commit comments