zoukankan      html  css  js  c++  java
  • spfa判负环

    输入输出格式

    输入格式:

    第一行一个正整数T表示数据组数,对于每组数据:

    第一行两个正整数N M,表示图有N个顶点,M条边

    接下来M行,每行三个整数a b w,表示a->b有一条权值为w的边(若w<0则为单向,否则双向)

    输出格式:

    共T行。对于每组数据,存在负环则输出一行"YE5"(不含引号),否则输出一行"N0"(不含引号)。

    输入输出样例

    输入样例#1: 
    2
    3 4
    1 2 2
    1 3 4
    2 3 1
    3 1 -3
    3 3
    1 2 3
    2 3 4
    3 1 -8
    
    输出样例#1: 
    N0
    YE5
    

    说明

    N,M,|w|≤200 000;1≤a,b≤N;T≤10 

    大提醒:多组数据初始化一定要彻底

    1.spfa的BFS形式判负环,但是比较慢,经常会T

    思想:如果有一个点入队超过n次,说明存在负环。

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<queue>
     4 #define inf 2147483600
     5 using namespace std;
     6 const int N=500002;
     7 struct node{
     8     int v,c,ne;
     9 }e[N*2];
    10 int n,m,tot,h[N];
    11 void add(int u,int v,int c)
    12 {
    13     tot++;e[tot].v=v;e[tot].c=c;e[tot].ne=h[u];h[u]=tot;
    14 }
    15 int v[N],d[N],in[N],cnt[N];
    16 queue<int>q;
    17 bool fg;
    18 void spfa(int s)
    19 {
    20     for(int i=1;i<=n;i++) d[i]=inf,v[i]=0;
    21     v[s]=1;d[s]=0;q.push(s);
    22     while(!q.empty())
    23     {
    24         int ff=q.front();q.pop();v[ff]=0;
    25         in[ff]=1;cnt[ff]++;
    26         if(cnt[ff]>=n+1){fg=1;return;}
    27         for(int i=h[ff];i;i=e[i].ne)
    28         {
    29             int rr=e[i].v;
    30             if(d[rr]>d[ff]+e[i].c)
    31             {
    32                 d[rr]=d[ff]+e[i].c;
    33                 if(!v[rr])
    34                  v[rr]=1,q.push(rr);
    35             }
    36         }
    37     }
    38 }
    39 int T;
    40 int main()
    41 {
    42     scanf("%d",&T);
    43     while(T--)
    44     {
    45          scanf("%d%d",&n,&m);
    46          for(int i=1;i<=n;++i) h[i]=in[i]=cnt[i]=0;
    47          tot=0;fg=0;
    48          for(int i=1;i<=m;i++)
    49          {
    50              int x,y,z;scanf("%d%d%d",&x,&y,&z);
    51              add(x,y,z);
    52               if(z>0) add(y,x,z);    
    53          }
    54          for(int i=1;i<=n;++i)
    55          {
    56              if(!in[i]) spfa(i);
    57              if(fg) break;
    58          }
    59          if(!fg)cout<<"N0"<<endl;
    60          else cout<<"YE5"<<endl;
    61     }
    62     return 0;
    63 }
    View Code

    2.spfa的DFS形式判负环,比BFS要快很多

    思想:初始化,d[i]=0;枚举每个点去找负环

    再进行松弛操作的同时如果一个点被松弛到两次,说明存在负环。

    因为初始dis为0,所以只能通过负边来更新d[],而一但一个点被松弛了多次,那么一定存在负环。

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<queue>
     4 #define inf 2147483600
     5 using namespace std;
     6 const int N=500002;
     7 struct node{
     8     int v,c,ne;
     9 }e[N*2];
    10 int n,m,tot,h[N];
    11 void add(int u,int v,int c)
    12 {
    13     tot++;e[tot].v=v;e[tot].c=c;e[tot].ne=h[u];h[u]=tot;
    14 }
    15 int v[N],d[N],in[N],cnt[N];
    16 queue<int>q;
    17 bool fg;
    18 void spfa(int u)
    19 {
    20    if(fg) return;
    21    v[u]=1;
    22    for(int i=h[u];i;i=e[i].ne)
    23    {
    24           int rr=e[i].v;
    25           if(d[rr]>d[u]+e[i].c)
    26           {
    27                 d[rr]=d[u]+e[i].c;
    28                 if(v[rr] || fg){fg=1;break;}
    29                 spfa(rr);
    30           }
    31    }
    32    v[u]=0;
    33 }
    34 int T;
    35 int main()
    36 {
    37     scanf("%d",&T);
    38     while(T--)
    39     {
    40          scanf("%d%d",&n,&m);
    41          for(int i=1;i<=n;++i) h[i]=v[i]=0,d[i]=0;
    42          tot=0;fg=0;
    43          for(int i=1;i<=m;i++)
    44          {
    45              int x,y,z;scanf("%d%d%d",&x,&y,&z);
    46              add(x,y,z);
    47               if(z>0) add(y,x,z);    
    48          }
    49          for(int i=1;i<=n;++i)
    50          {
    51              spfa(i);
    52              if(fg) break;
    53          }
    54          if(!fg)cout<<"N0"<<endl;
    55          else cout<<"YE5"<<endl;
    56     }
    57     return 0;
    58 }
    View Code
  • 相关阅读:
    01_javaSE面试题:自增变量
    SpringBoot(二十)_404返回统一异常处理结果
    MD5加密工具代码
    SpringBoot(十九)_spring.profiles.active=@profiles.active@ 的使用
    读取本地文件转化成MultipartFile
    remote: http basic: access denied fatal: authentication failed for '‘解决办法
    git报错_you are not allowed to push code to protected branches on this project
    SpringBoot(十八)_springboot打成war包部署
    sql优化问题笔记(mysql)
    gitbook 简单使用
  • 原文地址:https://www.cnblogs.com/adelalove/p/8492193.html
Copyright © 2011-2022 走看看