spfa + slf优化

最近在练习费用流 , 不是要用spfa吗 ,我们教练说:ns学生写朴素的spfa说出去都让人笑 。

QwQ,所以就去学了一下优化 。

slf优化就是双向队列优化一下,本来想用lll优化,可是优化后我tm居然t了(那道题特地卡spfa),所以lll优化太迷了 ,还是只用slf优化好 。

 1 #include <iostream>
 2 #include <cstdlib>
 3 #include <cstring>
 4 #include <cstdio>
 5 #include <deque>
 6 const int inf = 1 << 30 , maxn = 100000 + 11 , M = 200000 + 11  ;
 7 using namespace std ;//1061109567
 8 int n , m , head[maxn]  , dis[maxn] , cnt , sum , tot ;
 9 bool mark[maxn] ;
10 struct id
11 {
12     int nxt ,to , val ;
13 } edge[M] ;
14 deque < int > Q ;
15
16
17 inline void Init ( )
18 {
19     freopen( "NSOOJ#10719.in" , "r" , stdin  ) ;
20     freopen( "NSOOJ#10719.out" , "w" , stdout ) ;
21 }
22
23 int read( )
24 {
25     char ch = getchar( ) ; int k = 1 , ret = 0 ;
26     while( ch < ‘0‘ || ch > ‘9‘ ) { if( ch == ‘-‘ ) k = -1 ; ch = getchar( ) ; }
27     while( ch >= ‘0‘ && ch <= ‘9‘ ) ret = ret * 10 + ch - ‘0‘ , ch = getchar( ) ;
28     return k * ret ;
29 }
30
31 void add( int u , int v , int va )
32 {
33     edge[++cnt].nxt = head[u] , edge[cnt].to = v ;
34     edge[cnt].val = va , head[u] = cnt ;
35 }
36
37 void input(  )
38 {
39     n = read()  , m = read( ) ;
40     int u ,v , c ;
41     memset( head , -1 , sizeof(head)) ;
42     for( int x = 1 ; x <= m ; ++x )
43     {
44         u = read( ) , v = read( ) , c = read( ) ;
45         add( u ,v , c )  ;
46     }
47 }
48
49 void spfa( )
50 {
51     memset( dis , 127/2 , sizeof(dis) ) ;
52     dis[1] = 0 , mark[1] = true ;
53     Q.push_back( 1 ) ;
54     while( !Q.empty( ) )
55     {
56         int u = Q.front( ) ; Q.pop_front( ) ; mark[u] = false ;
57
58         for( int i = head[u] ; ~i ; i = edge[i].nxt )
59         {
60             int v = edge[i].to ;
61             if( dis[v] > dis[u] + edge[i].val )
62             {
63                 dis[v] = dis[u] + edge[i].val ;
64                 if( !mark[v] )
65                 {
66                     mark[v] = true ;
67                     if( Q.empty( ) || dis[v] > dis[Q.front( )]  ) Q.push_back( v ) ;
68                     else Q.push_front( v ) ;
69
70                 }
71
72             }
73         }
74     }
75     if( dis[n] == 1061109567 ) printf( "%d\n" , -1 ) ;
76     else printf( "%d\n" , dis[n] ) ;
77 }
78
79
80 int main( )
81 {
82 //    Init( ) ;
83     input( ) ;
84     spfa( ) ;
85 //    fclose( stdin ) ;
86 //       fclose( stdout ) ;
87     return 0 ;
88 }
时间: 2024-10-13 12:06:45

spfa + slf优化的相关文章

spfa及slf优化

spfa,不用多讲了吧,相当实用的BF队列优化算法,裸代码如下 program spfa; var pre,last,other,long:array[0..1000001] of longint; d,short:array[0..1000001] of longint; ok:array[0..1000001] of boolean; head,tail,m,n,i,j,k,tot,x,y,z:longint; procedure add(x,y,z:longint); begin inc(

蓝桥杯 算法提高 道路和航路 满分AC ,SPFA算法的SLF优化,测试数据还是比较水的,貌似没有重边

算法提高 道路和航路 时间限制:1.0s   内存限制:256.0MB 问题描述 农夫约翰正在针对一个新区域的牛奶配送合同进行研究.他打算分发牛奶到T个城镇(标号为1..T),这些城镇通过R条标号为(1..R)的道路和P条标号为(1..P)的航路相连. 每一条公路i或者航路i表示成连接城镇Ai(1<=A_i<=T)和Bi(1<=Bi<=T)代价为Ci.每一条公路,Ci的范围为0<=Ci<=10,000:由于奇怪的运营策略,每一条航路的Ci可能为负的,也就是-10,000

HDU 1535 Invitation Cards (最短路,附SLF优化SPFA)

题目: http://acm.hdu.edu.cn/showproblem.php?pid=1535 题意: 有向图,求点1到点2-n的最短距离之和以及点2-n到点1的最短距离之和 方法: 1.跑1为原点的最短路 2.反向建图(把有向图的边反向,(u,v,w)变成(v,u,w)),跑1为原点的最短路 3.将两者距离之和加和即可(注意用 long long ,int会溢出) 1 void input() 2 { 3 scanf("%d%d", &n, &m); 4 g1.

spfa的SLF优化

spfa的SLF优化就是small label first 优化,当加入一个新点v的时候如果此时的dis[v]比队首dis[q.front()]还要小的话,就把v点加入到队首,否则把他加入到队尾,因为先扩展最小的点可以尽量使程序尽早的结束,一种方法可以用模拟队列,head,tail,但是由于不知道q的数组开多大,所有用双端队列deque<int>q更好些 模板: void spfa(int s) { deque<int>q; memset(dis,inf,sizeof(dis));

spfa及其优化

发现spfa居然也有优化,十分的震惊,现在由我细细道来(#^.^#) Description    给你一个有向且边权全部非负的图,输出1到n的最短路.Input    第一行两个自然数n(n<=100000)和m(m<=200000),表示点数和边数.接下来m行,每行3个数a,b,l,其中1<=a,b<=n,l<=1000.Output    仅一个整数,为1到n的最短路.如果无解,输出-1.Sample Input10 101 5 461 10 502 7 233 4 4

Dijkstra、Dij + heap、Floyd、SPFA、 SPFA + SLF Template

Dijkstra in Adjacency matrix : int Dijkstra(int src,int tec, int n){ bool done[1005]; int d[1005]; memset(done,0,sizeof(done)); map[0][src] = 0;//巧妙之处,加入超级源点0 for(int i = 0;i <= n;i++) d[i] = (i == src ? 0 : 1000000); for(int i = 0;i <= n;i++){//最多执

HDU 4284 状压dp+spfa堆优化

题意: 给定n个点 m条无向边 d元. 下面m行表示每条边 u<=>v 以及花费 w 下面top 下面top行 num c d 表示点标为num的城市 工资为c 健康证价格为d 目标是经过给定的top个城市,当到达该城市时,必须马上购买该城市的健康证并打工赚钱(每个城市只打工1次) 问从1城市出发,最后回到1城市,能否收集到所有的健康证 思路: 由于top很小,所以状压dp dp[i][tmp]表示当前处于i点 经过城市的状态为tmp时 身上最多的钱. 首先对dis数组floyd 跑出最短路,

SPFA+SLF+LLL优化模板

1 #include<algorithm> 2 #include <iostream> 3 #include <cstdlib> 4 #include <cstring> 5 #include <climits> 6 #include <cstdio> 7 #include <string> 8 #include <cmath> 9 #include <stack> 10 #include <

最短路--spfa+队列优化模板

spfa普通版就不写了,优化还是要的昂,spfa是可以判负环,接受负权边和重边的,判断负环只需要另开一个数组记录每个结点的入队次数,当有任意一个结点入队大于点数就表明有负环存在 1 #include<stdio.h> //spfa基本上要这些头文件 2 #include<string.h> 3 #include<queue> 4 using namespace std; 5 6 void spfa(int s,int p){ 7 memset(vis,0,sizeof(