1. 程式人生 > >【模板】前向星 SPFA求最短(長)路

【模板】前向星 SPFA求最短(長)路

代碼 poj ostream name 兩個 col spfa ron esp

之前一個改自別人的模板竟然在一道題上TLE了,而代碼也實在醜陋,網上找得到的模板也大多跑得慢(vector存圖)或代碼醜陋、殘疾(無初始化函數的模板能叫模板嗎?),索性自己重新寫了一個。

題是POJ1716(差分約束模型),需要求最長路,其實跟最短路也只有很小的差別。

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<vector>
 4 #include<cstring>
 5 #include<queue>
 6 using namespace std;
 7 // 最長路,改為最短路只需修改兩個註釋了的地方
8 const int MAXN = 10011, MAXM = 30033; 9 int N,dis[MAXN],cnt[MAXN],head[MAXN],tot; 10 bool inq[MAXN]; 11 struct Edge{ 12 int v, w, nxt; 13 }e[MAXM]; 14 void init(int n){ 15 tot = 0; N = n; 16 memset(head,-1,sizeof head); 17 memset(inq,0,sizeof inq); 18 memset(cnt,0,sizeof cnt); 19 fill(dis,dis+N+1
,-1e9); /// 1 20 } 21 void addEdge(int u,int v,int w){ 22 e[tot] = {v,w,head[u]}; 23 head[u] = tot++; 24 } 25 bool SPFA(int s){ 26 queue<int> que; 27 inq[s] = 1; dis[s] = 0; 28 que.push(s); 29 while(!que.empty()){ 30 int x = que.front(); que.pop(); 31 inq[x] = 0
; 32 for(int i = head[x];~i;i = e[i].nxt){ 33 int v = e[i].v, w = e[i].w; 34 if(dis[v] < dis[x] + w){ /// 2 35 dis[v] = dis[x] + w; 36 if(!inq[v]){ 37 inq[v] = 1; que.push(v); 38 if(++cnt[v] > N) return 0; 39 } 40 } 41 } 42 } 43 return 1; 44 } 45 46 int n; 47 48 int main(){ 49 cin >> n; 50 init(10007); 51 for(int i = 0;i < n;++i){ 52 int a,b; 53 scanf("%d%d",&a,&b); 54 addEdge(a,b+1,2); 55 } 56 for(int i = 0;i <= 10000;++i){ 57 addEdge(i,i+1,0); 58 addEdge(i+1,i,-1); 59 } 60 SPFA(0); 61 printf("%d\n",dis[10001]); 62 63 return 0; 64 }

【模板】前向星 SPFA求最短(長)路