模板前向星 SPFA求最短(长)路

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了模板前向星 SPFA求最短(长)路相关的知识,希望对你有一定的参考价值。

之前一个改自别人的模板竟然在一道题上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求最短(长)路的主要内容,如果未能解决你的问题,请参考以下文章

最短路 SPFA()链式前向星

HDU - 1535 Invitation Cards 前向星SPFA

POJ 2387 链式前向星下的SPFA

POJ 1511 链式前向星+SPFA

最短路 spfa 算法 && 链式前向星存图

HDU 1317XYZZY spfa+判断正环+链式前向星(感觉不对,但能A)