SPFA 最短路
阿新 • • 發佈:2017-05-06
有意 using span 修改 一個 push family memset spfa
GeneralLiu
最短路
什麽意思呢
其實就是字面意思嘍
解法多樣
就只介紹 SPFA 了
每次 用一個 "有意義" 的點 更新與之相連點 的 dis 值
(至於 dis[]數組 dis[i] 表示 源點 到 i 的最短 距離 , dis初始化無窮大)
每次 "有意義" 的更新 就把 被更新點 加入 "有意義點 的 隊列" 之中去
(至於 "有意義" 就是 dis 值 變小了,變小了 才有可能 把其他點的 dis 值更新得 更小)
到隊列為空時 算法結束 dis 數組 即 源點到各點的最短距離
可以用此圖 參考代碼 模擬一下
例題
洛谷 P2951 [USACO09OPEN]捉迷藏Hide and Seek
先求出 dis[] 數組
再遍歷 dis[] 數組 找出最遠 節點 長度 數量
代碼
#include<bits/stdc++.h> using namespace std; #define N 20004 #define M 50004 int t=1,s,dis[N],n,m,head[N],to[M<<1],next[M<<1],cnt; bool b[N]; queue<int>que; // "有意義"的隊列int read(){ //讀入優化 int ans=0,ch=getchar(); for(;!isdigit(ch);ch=getchar()); for(;isdigit(ch);ch=getchar()) ans=ans*10+ch-‘0‘; return ans; } int main(){ n=read(),m=read(); for(int i=1,x,y;i<=m;i++){ x=read(),y=read(); next[++cnt]=head[x]; // 鏈式前向星to[cnt]=y; head[x]=cnt; next[++cnt]=head[y]; to[cnt]=x; head[y]=cnt; } memset(dis,127/3,sizeof(dis)); // 置一個很大的數 b[1]=1; // 有意義 dis[1]=0; que.push(1); //push for(int u,v;!que.empty();){ u=que.front(); que.pop(); b[u]=0; // 已經取出 變為無意義 for(int j=head[u];j;j=next[j]){ v=to[j]; if(dis[v]>dis[u]+1){ // 是否成功修改 dis[v]=dis[u]+1; if(!b[v]){ // 是否在隊列中 b[v]=1; que.push(v); } } } } for(int i=2;i<=n;i++){ // 找答案 if(dis[t]<dis[i]){ t=i; s=1; } else if(dis[t]==dis[i])s++; } printf("%d %d %d",t,dis[t],s); return 0; }
SPFA 最短路