最短路是图论中的基础,单源最短路SSSP是基础的基础(2333自己发明的名言……
关于图论算法之前只说了存图……唔今天先复习一下SSSP的几个算法。
Dijkstra
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 |
#include<iostream> #include<cstdio> #include<algorithm> #include<vector> #include<cmath> #include<queue> #define PB(x) push_back(x) #define PS(x) push(x) #define MP(x,y) make_pair(x,y) using namespace std; typedef long long LL; const int MAXN=10000; const int INF=2147483647; const int NINF=-1<<31; const int ERR=-1; bool getint(int &x){ x=0;int n=1; char c=getchar(); while(((c-'0')>=10)||((c-'0')<0)){n=1;if(c=='-')n=-1;c=getchar();if((int)c==-1)return false;} while(((c-'0')<10)&&((c-'0')>=0)){x=x*10+(c-'0');c=getchar();}x*=n; return true; } void priint(int k){if(k==0)putchar('0');if(k<0){putchar('-');k=-k;} int t=0;char ch[30]; while(k>0)ch[++t]=k%10,k/= 10; while(t)putchar(ch[t--]+'0'); putchar(32); } //以上是渣优化…… typedef pair<int,int> PII; priority_queue<PII,vector<PII>,greater<PII> > Q; struct P{int t;int v; P():t(0),v(0){} P(int st,int sv){t=st;v=sv;} }; vector<P> M[MAXN]; int D[MAXN]; int n,m;int s,t; int main(){ getint(n);getint(m); while(m--){ int s,t,v; getint(s);getint(t);getint(v); M[s].PB(P(t,v)); } for(int i=0;i<n;i++){D[i]=INF>>1;} getint(s); Q.PS(MP(0,s));D[s]=0; while(!Q.empty()){ PII pp = Q.top(); Q.pop();int ps=pp.second; if(pp.first != D[ps]) {continue;} for(int i = 0; i < M[ps].size(); i++) { int pt = M[ps][i].t; int pv = M[ps][i].v; if(D[pt] > D[ps] + pv) { D[pt] = D[ps] + pv; Q.PS(MP(D[pt], pt)); } } } for(int i=0;i<n;i++) { priint(D[i]); } return 0; } |
SPFA
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 |
#include<iostream> #include<cstdio> #include<algorithm> #include<vector> #include<cmath> #include<queue> #define PB(x) push_back(x) #define PS(x) push(x) #define MP(x,y) make_pair(x,y) using namespace std; typedef long long LL; const int MAXN=10000; const int INF=2147483647; const int NINF=-1<<30; const int ERR=-1; bool getint(int &x){ x=0;int n=1; char c=getchar(); while(((c-'0')>=10)||((c-'0')<0)){n=1;if(c=='-')n=-1;c=getchar();if((int)c==-1)return false;} while(((c-'0')<10)&&((c-'0')>=0)){x=x*10+(c-'0');c=getchar();}x*=n; return true; } void priint(int k){if(k==0)putchar('0');if(k<0){putchar('-');k=-k;} int t=0;char ch[30]; while(k>0)ch[++t]=k%10,k/= 10; while(t)putchar(ch[t--]+'0'); putchar(32); } queue<int> Q; struct P{int t;int v; P():t(0),v(0){} P(int st,int sv){t=st;v=sv;} }; vector<P> M[MAXN]; int D[MAXN];bool inQ[MAXN];int T[MAXN]; int n,m;int s,t; bool NL; int main(){ getint(n);getint(m); while(m--){ int s,t,v; getint(s);getint(t);getint(v); M[s].PB(P(t,v)); } for(int i=0;i<n;i++){D[i]=INF>>1;} getint(s); D[s]=0; Q.PS(s);inQ[s]=1; while(!(Q.empty()||NL)){ int ps=Q.front();Q.pop(); inQ[ps]=0; for(int i=0;i<M[ps].size();++i){ int pt=M[ps][i].t;int pv=M[ps][i].v; if(D[pt]>D[ps]+pv){ D[pt]=D[ps]+pv; Q.PS(pt);inQ[pt]=1; if(++T[pt]>n){NL=1;} } } } if(NL){printf("Native Loop");return 0;} for(int i=0;i<n;i++){ priint(D[i]); } return 0; } |
SPFA不仅是SSSP的一个算法,而更多的是一种思想。