Luogu 3385 sentence negative ring template

Title: https://www.luogu.org/problemnew/show/P3385

There is a method for DFS to judge the negative ring. See "Optimization and Application of SPFA Algorithm" (Jiang Biye).

An excerpt from the text:

  First, assume that there is a point s initially, from which we can find a positive ring (that is, take s as the starting point to walk around the ring, and dis[x] when passing through any point is greater than 0). The following proves that the reassignment of a point x on the ring does not affect the search of the positive ring.
  Suppose that the predecessor of x on the ring is y. Originally, when looking for a positive ring, dis[y]+w(y,x)>dis[x], and then continue to iterate from x. And if dis[x] is reassigned dis[x]'>=dis[y]+w(y,x), it seems to stop when it reaches x, and if dis[x] is reassigned dis [x]'>=dis[y]+w(y,x), it seems that it stops when it reaches x, and if dis[x] is reassigned dis[x]'>=dis[y]+ w(y,x), it seems that the iteration stops when it reaches x, and there is no need to transition from y to x. There is no difference between the two. And so on, it must be possible to find a starting point that leads to a positive cycle.
  The initial assumption is clearly established, otherwise we can divide the positive ring into several segments, and the sum of the edge weights of each segment is <= 0, which contradicts the premise of the positive ring, and the proposition is proved.

Actually a little bit clueless. Research later.

For this question, the dfs only got 40 points, so using the fast reading + spfa handwriting queue to achieve 1000+ms will be able to AC.

I used a circular queue and found that the condition of h!=t+1 is very useful.

#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
#define ll long long
using namespace std;
const int N=4005,M=6005,INF=N<<5-5;
int T,n,m,head[N],xnt,cnt[N],q[N<<5],h,t;
ll dis[N];
bool in[N];
struct Edge{
    int next,to,w;
    Edge(int n=0,int t=0,int w=0):next(n),to(t),w(w) {}
}edge[M<<1];
int read()
{
    int ret=0;char ch;bool fx=0;
    ch=getchar();
    while(ch<'0'||ch>'9')
    {
        if(ch=='-')fx=1;ch=getchar();
    }
    while(ch>='0'&&ch<='9')
    {
        ret = ret * 10 + ( int ) ch- ' 0 ' ;
        ch=getchar();
    }
    return fx? - right: right;
}
void add(int x,int y,int z)
{
    edge[++xnt]=Edge(head[x],y,z);head[x]=xnt;
}
bool spfa()
{
    memset(dis,1,sizeof dis);memset(in,0,sizeof in);
    memset(cnt,0,sizeof cnt);h=1;t=1;
    q[1]=1;in[1]=1;dis[1]=0;
    while(h!=t+1)
    {
        int k=q[h++];in[k]=0;if(h>INF)h=1;
        for(int i=head[k],v;i;i=edge[i].next)
            if(dis[k]+edge[i].w<dis[v=edge[i].to])
            {
                dis[v]=dis[k]+edge[i].w;cnt[v]=cnt[k]+1;
                if(cnt[v]>=n)return true;
                if(!in[v])
                {
                    in[v]=1;t++;
                    if(t>INF)t=1;q[t]=v;
                }
            }
    }
    return false;
}
intmain ()
{
    T=read();
    while(T--)
    {
        memset(head,0,sizeof head);xnt=0;
        n=read();m=read();int x,y,z;
        for(int i=1;i<=m;i++)
        {
            x=read();y=read();z=read();add(x,y,z);
            if(z>=0)add(y,x,z);
        }
        if(spfa())printf("YE5\n");
        else printf("N0\n");
    }
    return 0;
}

 

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=324927721&siteId=291194637