[Negative ring problem solution] Use spfa And Bellman-Ford

Source: Internet
Author: User

Finally, I began to take graph theory seriously.

I have heard that I have been raising the group, and I have been moving very little. I have been learning some things since I started to improve my computer room.

Template question link

This is a question for finding negative loops. In theory, we all use spfa to judge negative loops.

But I think Bellman-Ford is better.

In addition, in this template question, the spfa has opened O2, and the bellman does not enable O2, which is faster than the spfa?

Why?

Because

About spfa

-- He is dead.

(The basic owner of the IDC is dijistra)

However, dijistra cannot solve the negative ring problem.

Therefore, select bellman and spfa (queue-optimized bellman)

You can also use other methods, such

 

Spfa dead algorithm ideas

Because when a negative ring occurs, it will keep repeating ......

Then TLE

Therefore, add a CNT array to the original spfa to record the number of times a team exists.

If the number of teams is greater than the number of points, it indicates that a negative ring must appear.

Therefore, you can add it to the judgment.

Digress

Previously, xzjds told me about the storage of the adjacent table, but later I found that it is generally called the chain forward star instead of the adjacent table ......

If not, Baidu

To store edges, you can also use vector containers and Xuanxue struct (which will be used in bellman)

Code
// luogu-judger-enable-o2#include<bits/stdc++.h>#define memset0(a) memset(a,0,sizeof a)#define memset1(a) memset(a,127,sizeof a)#define N 500005using namespace std;int tot,m,n,s;int ne[N], la[N], link[N], co[N], dis[N];int cnt[N];//importantbool vis[N];inline int read() {    int f = 1, x = 0; char ch;    do { ch = getchar(); if (ch == ‘-‘)f = -1; } while (ch<‘0‘ || ch>‘9‘);    do { x = x * 10 + ch - ‘0‘; ch = getchar(); } while (ch >= ‘0‘&&ch <= ‘9‘);    return f * x;}void add(int x, int y, int z){    tot++; ne[tot] = y; co[tot] = z; la[tot] = link[x]; link[x] = tot;}bool spfa(int s){    memset1(dis);    memset0(vis);    memset0(cnt);    queue<int>q;    q.push(s);    vis[s] = true;    dis[s] = 0;    while (!q.empty())    {        int now = q.front();        q.pop();        vis[now] = false;//?        if (cnt[now] >= n) return true;        for (int k = link[now]; k; k = la[k])        {            if (dis[ne[k]] > dis[now] + co[k])            {                dis[ne[k]] = dis[now] + co[k];                if (vis[ne[k]] == false)                {                    q.push(ne[k]);                    vis[ne[k]] = true;                    cnt[ne[k]]++;                    if (cnt[ne[k]] >= n) return true;                }            }        }    }    return false;}int main(){    int T=read();    while (T--)    {        memset0(link);        n = read(), m = read();        s = 1; tot = 0;;        for (int i = 1; i <= m; i++)        {            int x=read(), y=read(), z=read();            add(x, y, z);            if (z >= 0) add(y, x, z);        }        if(spfa(s))puts("YE5");        else puts("N0");    }    return 0;}
Spfa

Yes, it will be TLE without O2. Only 90 points.

Because this algorithm won't be optimized, we learned a better way to judge the negative ring of Bellman.

Bellman-Ford algorithm ideas

We can set the DIS array to 0 at the beginning.

First, perform all the relaxation operations (relaxing once)

Then relax again. If it can relax, there is a negative ring.

Compared with spfa, when the number of data points is small, the time is faster than spfa.

Of course, if the RP is not good, the spfa speed will be faster.

Why is there a problem every time?

The edge storage method is shown in daxie @ planet6174.

It is very mysterious but easy to use.

Code
#include<bits/stdc++.h>#define N 500005using namespace std;int tot,m,n,s;int dis[N];inline int read() {    int f = 1, x = 0; char ch;    do { ch = getchar(); if (ch == ‘-‘)f = -1; } while (ch<‘0‘ || ch>‘9‘);    do { x = x * 10 + ch - ‘0‘; ch = getchar(); } while (ch >= ‘0‘&&ch <= ‘9‘);    return f * x;}struct eg{    int u,v,w;    eg(int u = 0, int v = 0, int w = 0) : u(u), v(v), w(w) {}} edge[N];bool bellman_ford(){    memset(dis,0,sizeof(dis));    for(int i=1;i<=n-1;i++)        for(int j=1;j<=m;j++)            if (dis[edge[j].u] + edge[j].w < dis[edge[j].v])                dis[edge[j].v] = dis[edge[j].u] + edge[j].w;    for (int j = 1; j <= m; j++)        if (dis[edge[j].u] + edge[j].w < dis[edge[j].v])            return true;    return false;}int main(){    int T=read();    while (T--)    {        n = read(), m = read();;        for (int i = 1; i <= m; i++)        {            edge[i].u=read(), edge[i].v=read(), edge[i].w=read();            edge[i].u--; edge[i].v--;            if (edge[i].w >= 0) {                ++i; ++m; edge[i] = eg(edge[i - 1].v, edge[i - 1].u, edge[i - 1].w);            }        }        if(bellman_ford()) puts("YE5");        else puts("N0");    }    return 0;}
Bellman-Ford

That's it.

[Negative ring problem solution] Use spfa And Bellman-Ford

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.