利用Burp Suite對OWASP Juice Shop進行滲透測試
阿新 • • 發佈:2022-04-29
演算法介紹:
SPFA(Shortest Path Faster Algorithm)是Bellman-Ford演算法的一種佇列實現,減少了不必要的冗餘計算。
演算法流程:
演算法大致流程是用一個佇列來進行維護。 初始時將源加入佇列。 每次從佇列中取出一個元素,並對所有與他相鄰的點進行鬆弛,若某個相鄰的點鬆弛成功,則將其入隊。 直到佇列為空時演算法結束。
維護一個佇列,裡面存放所有需要進行迭代的點。初始時佇列中只有一個點S。用一個布林陣列記錄每個點是否處在佇列中。
每次迭代,取出隊頭的點v,依次列舉從v出發的邊v->u,設邊的長度為len,判斷Dist[v]+len是否小於Dist[u],若小於則改進Dist[u],將Fa[u]記為v,並且由於S到u的最短距離變小了,有可能u可以改進其它的點,所以若u不在佇列中,就將它放入隊尾。這樣一直迭代下去直到佇列變空,也就是S到所有的最短距離都確定下來,結束演算法。
若一個點入隊次數超過n,則有負權環。
//P2850Wormholes G如果農場裡有負環則一定可以穿越回出發時刻之前 #include<cstdio> #include<cstring> #include<queue> #include<iostream> using namespace std; const int maxm=3000*2+5,maxn=500+5; struct Edge{ int to,next,dis; }e[maxm]; int F,n,m,W,len,head[maxn]; void Insert(int x,int y,int dis){ e[++len].to=y; e[len].dis=dis; e[len].next=head[x]; head[x]=len; } int d[maxn];//d[i]i到st的最短距離 int cnt[maxn];//cnt[i]i入隊的次數,如果超過maxk則說明有負環 bool vis[maxn];//用於記錄有沒有在佇列裡 bool spfa(int st){ for(int i=1;i<=n;++i)d[i]=0x3f3f3f3f; for(int i=1;i<=n;++i)cnt[i]=0; memset(vis,0,sizeof(vis)); queue<int>q; q.push(st); cnt[st]++; d[st]=0; vis[st]=1; while(!q.empty()){ int x=q.front(); q.pop(); vis[x]=0; for(int i=head[x];i;i=e[i].next){ int v=e[i].to; if(d[v]>d[x]+e[i].dis){ d[v]=d[x]+e[i].dis; if(!vis[v]){//如果x可以更新v 則v入隊 q.push(v);vis[v]=1; cnt[v]++; if(cnt[v]>n){ return 1; } } } } } return 0; } void work(){ scanf("%d%d%d",&n,&m,&W); int st=0;len=0; memset(head,0,sizeof(head)); for(int i=1;i<=m;++i){ int x,y,dis; if(!st)st=x; scanf("%d%d%d",&x,&y,&dis); Insert(x,y,dis);Insert(y,x,dis); } for(int i=1;i<=W;++i){//處理蟲洞 int x,y,dis; scanf("%d%d%d",&x,&y,&dis); Insert(x,y,-dis); } if(spfa(1)){ printf("YES\n"); } else { printf("NO\n"); } } int main(){ scanf("%d",&F); while(F--) work(); return 0; }
SPFA 在形式上和寬度優先搜尋非常類似,不同的是寬度優先搜尋中一個點出了佇列就不可能重新進入佇列,但是SPFA中一個點可能在出佇列之後再次被放入佇列,也就是一個點改進過其它的點之後,過了一段時間可能本身被改進,於是再次用來改進其它的點,這樣反覆迭代下去。設一個點用來作為迭代點對其它點進行改進的平均次數為k,有辦法證明對於通常的情況,k在2左右。
在實際的應用中SPFA的演算法時間效率不是很穩定,為了避免最壞情況的出現,通常使用效率更加穩定的Dijkstra演算法。
https://www.cnblogs.com/Jason-Damon/p/3787756.html
update2022.1.16
關於堆優化dijistra不能求最長路,spfa詐屍
dijistra本身基於貪心思想,如果是最短路,區域性的最優解 一定是全域性最優解的一部分,而最長路不一樣,區域性最優解不一定是全域性最優解。
求最長路還是要用spfa(改成負邊權跑最短路),由於spfa可以反覆更新,可以保證答案的正確性,但願最長路不會卡spfa