• spfa负环判断


    正常spfa中加入time数组,循环判断一个点是否入队并更新了n次以上注意是 > n!!其余的没有什么问题

    扩展的还有,寻找所有负环上的点,这个可以在spfa中time 发现负环的时候,对那个点进行dfs操作,找到所有的负环上的点即可

    void dfs(int u)
    {
        cir[u] = 1;
        for(int i = id[u];~i;i = edge[i].pre)
        {
            if(!cir[edge[i].to])
                dfs(edge[i].to);
        }
    }
    

     一下负权回路代码以poj3259为例(poj又挂了,暂时还没发交题测试,欢迎大家来找bug)

    /*
    spfa负环的判断
    */
    #include <iostream>
    #include <cstdio>
    #include <string.h>
    #include <queue>
    #include <algorithm>
    #define inf (1 << 29)
    using namespace std;
    typedef long long ll;
    const int maxn = 600;
    const int maxm = 3e3;
    int id[maxn],cnt;
    struct node{
        int to,cost,pre;
    }e[maxm * 2];
    int dis[maxn];
    int vis[maxn];
    int time[maxn];
    
    queue<int> q;
    void init()
    {
        while(q.size())q.pop();
        memset(time,0,sizeof(time));
        memset(vis,0,sizeof(vis));
        memset(id,-1,sizeof(id));
        cnt = 0;
    }
    void add(int from,int to,int cost)
    {
        e[cnt].to = to;
        e[cnt].cost = cost;
        e[cnt].pre = id[from];
        id[from] = cnt++;
    }
    int spfa(int s,int n)
    {
        for(int i= 0;i <= n;i++)
            dis[i] = inf;
        q.push(s);
        vis[s] = 1;
        time[s] = 1;
        dis[s] = 0;
    
        while(q.size())
        {
            int now = q.front();
            q.pop();
            vis[now] = 0;
            for(int i = id[now];~i;i = e[i].pre)
            {
                int to = e[i].to;
                int cost = e[i].cost;
                if(dis[to] > dis[now] + cost)
                {
                    dis[to] = dis[now] + cost;
                    if(!vis[to])
                    {
                        vis[to] = 1;
                        q.push(to);
                        if(++time[to] > n)
                            return 0;
                    }
                }
            }
        }
        return 1;
    }
    int main()
    {
        int t;
        scanf("%d",&t);
        while(t--)
        {
            int n,m,k;
            scanf("%d%d%d",&n,&m,&k);
            init();
            int a,b,x;
            for(int i = 1;i <= m;i++)
            {
                scanf("%d%d%d",&a,&b,&x);
                add(a,b,x);
                add(b,a,x);
            }
            for(int i = 1;i <= k;i++)
            {
                scanf("%d%d%d",&a,&b,&x);
                add(a,b,-x);
            }
            int op = spfa(1,n);
    
            if(op)
                printf("NO
    ");
            else
                printf("YES
    ");
        }
        return 0;
    }
    
  • 相关阅读:
    阿里云下Linux MySQL的安装
    protocol buffer相关
    Unity NGUI UIPanel下对粒子的剪裁
    NGUI中UILabel用省略号替换超出显示区域的内容
    Go交叉编译
    Unity3d使用未破解的TexturePacker
    编程之美 找出符合条件的整数
    算法导论~
    hadoop资料汇总(网上)
    SOE 中调用第三方dll
  • 原文地址:https://www.cnblogs.com/DF-yimeng/p/9399351.html
Copyright © 2020-2023  润新知