• 洛谷P3385 【模板】负环 DFS-SPFA 判负环 图论


    洛谷P3385 【模板】负环

    图论

    今天get了 一个 DFS-SPFA 判负环的方法

    一般的 BFS-SPFA 判负环 一般就是 不停地做,如果某点第 n+1次加入队列中,那么说明这个图存在负环
    然而我并不会证明,期望复杂度是 O(kM) k 大约是在 2 左右 但是其实对于一些极限数据,最坏可以
    把他卡到 O( NM) 额,这就直接炸飞了是不是,而且据说,一些数据比较强的题目,总会想到卡一卡SPFA
    的,

    然后我们换一种思路
    因为题目中一定存在一种 负环对吧,所以说假如你某段路径权值和为自然数的时候, 你这一段还不如
    不走对不对,你还不如直接从第一条负边开始走起,
    我们把每个点的 dist设为 0 ,dfs下去如果能够松弛的话就一直松弛下去,这时候的松弛还有另一个含义
    ,因为你设的每个的dist是 0 ,所以能够松弛还说明的到 从起点 s 到这个点的 路径和一直是 负的,
    我们把在这条路径中的点标记一下,如果下次 有松弛过的点 到这个点,那么说明就有负环

    另外 要注意从每一个点开始的 DFS-SPFA 求的只是求的 以他为起点的 负环是否存在,因为 每次dfs
    如果碰到 不能松弛就不 松弛了,那么也许后面还能够松弛,所以说要枚举每一个点作为松弛起点



    另外注意这题的坑点 YE'5' 和 N'0' 不包括引号
    然后 注意一下初始化 边表 head 以及cnt 都要清空

     1 #include <cstdio>
     2 #include <cmath>
     3 #include <cstdlib>
     4 #include <cstring>
     5 #include <string>
     6 #include <algorithm>
     7 #include <iomanip>
     8 #include <iostream> 
     9 using namespace std ; 
    10 
    11 const int maxn = 200011,maxm = 200011,inf = 1e9 ; 
    12 struct node{
    13     int to,val,pre ; 
    14 }e[2*maxm];
    15 int T,n,m,x,y,val,cnt ; 
    16 int head[maxn],dist[maxn] ; 
    17 bool flag ; 
    18 bool vis[maxn] ; 
    19 
    20 inline void addedge(int x,int y,int v) 
    21 {
    22     e[++cnt] = (node){ y,v,head[x] } ; 
    23     head[ x ] = cnt ; 
    24 }
    25 
    26 inline int read() 
    27 {
    28     char ch = getchar() ; 
    29     int x = 0 , f = 1 ; 
    30     while(ch<'0'||ch>'9') { if(ch=='-') f = -1 ; ch = getchar() ;  } 
    31     while(ch>='0'&&ch<='9') { x = x*10+ch-48 ; ch = getchar() ; } 
    32     return x*f ; 
    33 }
    34 
    35 inline void SPFA(int u) 
    36 {
    37     int v ; 
    38     vis[ u ] = 1 ; 
    39     for(int i=head[u];i;i = e[ i ].pre ) 
    40     {
    41         v = e[ i ].to ; 
    42         if( dist[ u ] + e[ i ].val < dist[ v ] ) 
    43         {
    44             dist[ v ] = dist[ u ] + e[ i ].val ; 
    45             if(vis[ v ]||flag) 
    46             {
    47                 flag = 1 ;  
    48                 break ; 
    49             }
    50             SPFA( v ) ; 
    51          }
    52     }    
    53     vis[ u ] = 0 ; 
    54 }
    55 
    56 int main()  
    57 {
    58     T = read() ;  
    59     while(T--) 
    60     {
    61         flag = 0 ; 
    62         cnt = 0 ; 
    63         n = read() ; m = read() ;  
    64         for(int i=1;i<=n;i++) dist[ i ] = 0,vis[ i ] = 0,head[ i ] = 0 ;    //0
    65         for(int i=1;i<=m;i++) 
    66         {
    67             scanf("%d%d%d",&x,&y,&val) ; 
    68             addedge(x,y,val) ; 
    69             if(val>=0) addedge(y,x,val) ;  
    70         }
    71         for(int i=1;i<=n;i++) 
    72         {
    73             SPFA( i ) ; 
    74             if(flag) break ; 
    75         } 
    76         if(flag) 
    77             printf("YE5
    ") ;  
    78         else 
    79             printf("N0
    ") ; 
    80             
    81     }
    82     return 0 ; 
    83 }
  • 相关阅读:
    TestNg线程池配置、执行次数配置、超时配置
    testng.xml文件结构组成及节点属性说明
    ReportNg 测试报告的定制修改【转】
    TestNg依赖详解(三)------灵活的文件配置依赖
    TestNg依赖高级用法之强制依赖与顺序依赖------TestNg依赖详解(二)
    TestNg依赖配置基础用法(单一方法依赖)------TestNg依赖详解(一)
    compareTo,Comparator和equals
    HashMap源码解析
    redis的相关知识
    IO模型
  • 原文地址:https://www.cnblogs.com/third2333/p/7029567.html
Copyright © 2020-2023  润新知