zoukankan      html  css  js  c++  java
  • 洛谷P3385 【模板】负环

    题目描述

    暴力枚举/SPFA/Bellman-ford/奇怪的贪心/超神搜索

    寻找一个从顶点1所能到达的负环,负环定义为:一个边权之和为负的环。

    输入输出格式

    输入格式:

    第一行一个正整数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
    

    说明

    n2000

    m3000

    10000w10000

    T10建议复制输出格式中的字符串。 本题数据感谢@negiizhao的精心构造,请不要使用玄学算法 本题数据有更新

      1 #include<iostream>
      2 #include<cstdio>
      3 #include<algorithm>
      4 #include<cstring>
      5 #include<queue>
      6 using namespace std;
      7 long long read()
      8 {
      9     long long x=0,f=1;
     10     char ch=getchar();
     11     while(ch>'9'||ch<'0')
     12     {
     13         if(ch=='-')
     14             f=-1;
     15         ch=getchar();
     16     }
     17     while(ch>='0'&&ch<='9')
     18     {
     19         x=x*10+ch-'0';
     20         ch=getchar();
     21     }
     22     return x*f;
     23 }
     24 const int maxn=20005;
     25 const int maxm=100010;
     26 int T,st=1,n,m,num;
     27 bool flag;
     28 bool vis[maxn];
     29 int dis[maxn],cnt[maxn],head[maxn],q[maxn];
     30 struct node
     31 {
     32     int v,w,nxt;
     33 } e[maxm*2];
     34 void add(int x,int y,int z)
     35 {
     36     e[++num].v=y;
     37     e[num].w=z;
     38     e[num].nxt=head[x];
     39     head[x]=num;
     40 }
     41 bool spfa()
     42 {
     43     int l=0,r=0;
     44     memset(dis,0x3f,sizeof(dis));
     45     memset(vis,0,sizeof(vis));
     46     memset(cnt,0,sizeof(cnt));
     47     memset(q,0,sizeof(q));
     48     vis[st]=1;
     49     cnt[st]=1;
     50     dis[st]=0;
     51     q[r++]=st;
     52     while(l!=r)
     53     {
     54         int u=q[l++];
     55         if(l>n)
     56             l=0;
     57         vis[u]=false;
     58         for(int i=head[u]; i; i=e[i].nxt)
     59         {
     60             if(dis[e[i].v]>dis[u]+e[i].w)
     61             {
     62                 dis[e[i].v]=dis[u]+e[i].w;
     63                 cnt[e[i].v]=cnt[u]+1;
     64                 if(cnt[e[i].v]>=n&&e[i].w<0)
     65                     return 1;
     66                 if(!vis[e[i].v])
     67                 {
     68                     vis[e[i].v]=1;
     69                     if(dis[e[i].v]>dis[q[l]])
     70                     {
     71                         l--;
     72                         if(l<0)
     73                             l=n;
     74                         q[l]=e[i].v;
     75                     }
     76                     else
     77                     {
     78                         q[r++]=e[i].v;
     79                         if(r>n)
     80                             r=0;
     81                     }
     82                 }
     83             }
     84         }
     85     }
     86     return false;
     87 }
     88 int main()
     89 {
     90     T=read();
     91     while(T--)
     92     {
     93         n=read(),m=read();
     94         memset(head,0,sizeof(head));
     95         num=0;
     96         for(int i=1; i<=m; i++)
     97         {
     98             int x=read(),y=read(),w=read();
     99             add(x,y,w);
    100             if(w>=0)
    101                 add(y,x,w);
    102         }
    103         if(spfa())
    104             printf("YE5
    ");
    105         else
    106             printf("N0
    ");
    107     }
    108     return 0;
    109 }
    View Code
  • 相关阅读:
    设计模式读书笔记
    effective_c++(第三版)读书笔记
    CS-Notes 操作系统读书笔记
    数据库笔记
    后台开发核心技术与应用读书笔记
    python3.7安装numpy pandas失败的处理方案
    线段树模板
    KMP算法
    离散实验——欧拉图的判定和应用
    堆排序算法及其实现
  • 原文地址:https://www.cnblogs.com/liweilin/p/10227120.html
Copyright © 2011-2022 走看看