SPFA ----模板 O(kE) (k一般不超过2)

原理:若一个点入队的次数超过顶点数V,则存在负环;

 1 #include "bits/stdc++.h"
 2
 3 using namespace std;
 4 const int maxN = 200010 ;
 5 struct Edge
 6 {
 7     int    to , next , w ;
 8 } e[ maxN ];
 9
10 int    n,m,cnt,p[ maxN ],Dis[ maxN ];
11 int    In[maxN ];
12 bool    visited[ maxN ];
13
14 void    Add_Edge ( const int x , const int y , const int z )
15 {
16     e[ ++cnt ] . to = y ;
17     e[ cnt ] . next = p[ x ];
18     e[ cnt ] . w = z ;
19     p[ x ] = cnt ;
20     return ;
21 }
22
23 bool    Spfa(const int S)
24 {
25     int    i,t,temp;
26     queue<int>    Q;
27     memset ( visited , 0 , sizeof ( visited ) ) ;
28     memset ( Dis , 0x3f , sizeof ( Dis ) ) ;
29     memset ( In , 0 , sizeof ( In ) ) ;
30
31     Q.push ( S ) ;
32     visited [ S ] = true ;
33     Dis [ S ] = 0 ;
34
35     while( !Q.empty ( ) )
36     {
37         t = Q.front ( ) ;Q.pop ( ) ;visited [ t ] = false ;
38         for( i=p[t] ; i ; i = e[ i ].next )
39         {
40             temp = e[ i ].to ;
41             if( Dis[ temp ] > Dis[ t ] + e[ i ].w )
42             {
43                 Dis[ temp ] =Dis[ t ] + e[ i ].w ;
44                 if( !visited[ temp ] )
45                 {
46                     Q.push(temp);
47                     visited[temp]=true;
48                     if(++In[temp]>n)return false;
49                 }
50             }
51         }
52     }
53     return true;
54 }
55
56 int main ( )
57 {
58     int    S , T ;
59
60     scanf ( "%d%d%d%d" , &n , &m , &S , &T ) ;
61     for(int i=1 ; i<=m ; ++i )
62     {
63         int x , y , _ ;
64         scanf ( "%d%d%d" , &x , &y , &_ ) ;
65         Add_Edge ( x , y , _  ) ;
66     }
67
68     if ( !Spfa ( S ) ) printf ( "FAIL!\n" ) ;
69     else               printf ( "%d\n" , Dis[ T ] ) ;
70
71     return 0;
72 }
时间: 2024-12-21 14:44:31

SPFA ----模板 O(kE) (k一般不超过2)的相关文章

畅通工程续 (SPFA模板Floy模板)

http://acm.hdu.edu.cn/showproblem.php?pid=1874 SPFA #include <iostream> #include <stdio.h> #include <string.h> #include <stdlib.h> #define N 1000001 using namespace std; int n,m; int v[202],dis[202]; struct node { int x,y,z,next; }

SPFA模板 Bellmanford优化版

SPFA模板: queue<int>Q; bool inq[510]; int dis[510],sumv[510]; int n,v[510*3],__next[510*3],e,w[510*3],first[510],cnts[510]; void AddEdge(int U,int V,int W) { v[++e]=V; w[e]=W; __next[e]=first[U]; first[U]=e; } bool spfa(const int &s) { memset(dis,

SPFA算法 O(kE)

主要思想是:     初始时将起点加入队列.每次从队列中取出一个元素,并对所有与它相邻的点进行修改,若某个相邻的点修改成功,则将其入队.直到队列为空时算法结束.     这个算法,简单的说就是队列优化的bellman-ford,利用了每个点不会更新次数太多的特点发明的此算法. SPFA 在形式上和广度优先搜索非常类似,不同的是广度优先搜索中一个点出了队列就不可能重新进入队列,但是SPFA中一个点可能在出队列之后再次被放入队列,也就是说一个点修改过其它的点之后,过了一段时间可能会获得更短的路径,于

hdu 1874 畅通工程续(SPFA模板)

畅通工程续 Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 82186    Accepted Submission(s): 31619 Problem Description 某省自从实行了很多年的畅通工程计划后,终于修建了很多路.不过路多了也不好,每次要从一个城镇到另一个城镇时,都有许多种道路方案可以选择,而某些方案要比另一些方案行走

HDU 1535 &amp;&amp; POJ 1511 Invitation Cards (SPFA 模板 + 反向建图)

Invitation Cards HDU: Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) POJ: Time Limit: 8000 MS     Memory Limit: 262144 K       Problem Description In the age of television, not many people attend theater performa

SPFA模板

Spfa是一种求单源最短路径的算法,时间复杂度为O(每个节点进队次数*边数):(然而对这个复杂度并不是很有概念,比堆优dij是快还是慢啊...) 算法流程: dis数组表示源点s到各点的距离,初始化dis[]={inf}; dis[s]=0; 源点进队: 队首出队: 对队首的每个邻接点做松弛操作: 对于每个被松弛的点,若不在队列中,则加入队列: 重复3~5至队列为空,此时的dis为最短路: STL的queue真是个好东西. 1 void spfa(int k){ 2 int i; 3 memse

spfa(模板)

spfa作为图论中的常用算法,深受各类出题人和各位OIer的喜爱: so,为了给大众创造福利,宝宝在此奉上spfa大发的思路和模板:以感谢社会, 感谢CCF,感谢CCTV, 感谢我的老师,感谢同学们, 感谢noi,感谢noip,感谢ioi, 感谢不辞辛劳的学长学姐, 感谢帮我改程序,被我烦死的xxy ~QAQ~······and so on; 程序和图解做得比较难看,就请大家见谅了!!~(≧▽≦)/~ 谢啦!!☆⌒(*^-゜)v 思路:见程序 #include<iostream> #inclu

最短路算法 -- SPFA模板

一.算法步骤 建立一个队列,初始时队列里只有起始点,再建立一个数组记录起始点到所有点的最短路径(该数组的初始值要赋为极大值,该点到它本身的路径赋为0,下面的模板中该数组为dist[]).然后执行松弛操作,用队列里有的点作为起始点去刷新到所有点的最短路,如果刷新成功且被刷新点不在队列中则把该点加入到队列最后.重复执行直到队列为空. 二.算法模板 1 struct Edge 2 { 3 int s, e, dist; //边的起点.终点.长度 4 5 Edge() {} 6 Edge(int s,

hdu 6437 /// 最小费用最大流 负花费 SPFA模板

题目大意: 给定n,m,K,W 表示n个小时 m场电影(分为类型A.B) K个人 若某个人连续看了两场相同类型的电影则失去W 电影时间不能重叠 接下来给定m场电影的 s t w op 表示电影的 开始时间s 结束时间t 看完这场电影则获得w 电影类型是op(0为A 1为B) 将一场电影拆成两个点 s t,两点间连线花费为-w容量为1 源点与所有电影的s点连线 花费为0容量为1 所有电影的t点与汇点连线 花费为0容量为1 若两场电影的时间不冲突 那么按时间顺序在之间连边 若类型相同 花费为W容量为