zoukankan      html  css  js  c++  java
  • UVA 558 SPFA 判断负环

    这个承认自己没看懂题目,一开始以为题意是形成环路之后走一圈不会产生负值就输出,原来就是判断负环,用SPFA很好用,运用队列,在判断负环的时候,用一个数组专门保存某个点的访问次数,超过了N次即可断定有负环(其实我觉得=N次了就可以断定了,当然这样是保险起见)。。。。别人还有用SPFA+DFS做的,还效率相当高,我还没怎么弄明白是怎么回事。。。还有,我突然想到讲最短路的时候说迪杰斯特拉不能用于有负权的图,这是为什么。。我还没想明白,先去睡觉吧。。。。

    关于dijstla为什么不能有负权,昨晚躺下之后就想明白了,dijstla最大特性在于其把当前d值最小的点给灰化了,下次不用再访问了,而负权如果存在,将使得已经发生灰化的点,d值会变小,这样就不得不取消灰化,但一旦取消,dijstla就永远无法走到终点,(将一直在d值最小的那个点徘徊),因此spfa通过用队列把d值发生变化的点加进去,因而解决了这个问题这只是题外话,不用说太多

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <queue>
    using namespace std;
    int u[2010],v[2010],w[2010],next[2010],first[1010];
    int d[1010],vis[1010],num[1010];
    int n,m,cnt,flag;
    void addedge(int a,int b,int c)
    {
        u[cnt]=a;
        v[cnt]=b;
        w[cnt]=c;
        next[cnt]=first[a];
        first[a]=cnt++;
    }
    void spfa()
    {
        int i,j;
        flag=0;
        for (i=0;i<=n;i++)
            d[i]=(1<<30);
        memset(vis,0,sizeof vis);
        memset(num,0,sizeof num);
        d[0]=0;
        queue <int> q;
        q.push(0);
        vis[0]=1;
        while (!q.empty())
        {
            int t=q.front();
            q.pop();
            vis[t]=0;
            for (j=first[t];j>=0;j=next[j])
            {
                int newnode=v[j];
                num[newnode]++;
                if (num[newnode]>n){
                       flag=1;
                        return;
                }
                if (d[newnode]>d[t]+w[j])
                {
    
                    d[newnode]=d[t]+w[j];
                    //cout<<newnode<<" "<<d[newnode]<<endl;
                    if (!vis[newnode]){
                        q.push(newnode);
                        vis[newnode]=1;
                 }
                }
            }
        }
    }
    int main()
    {
        int t,i,j;
        scanf("%d",&t);
        while (t--)
        {
            cnt=0;
            memset(first,-1,sizeof first);
            scanf("%d%d",&n,&m);
            int a,b,c;
            for (i=1;i<=m;i++){
    
              scanf("%d%d%d",&a,&b,&c);
              addedge(a,b,c);
            }
            spfa();
            if (!flag)
                puts("not possible");
            else
                puts("possible");
        }
        return 0;
    }
  • 相关阅读:
    面试问题
    知识点整合
    前端错误
    基于.NET平台常用的框架整理
    BFC和haslayout
    javascript面向对象
    javascript变量的作用域
    2014-05-26 总结
    2014-05-23 总结
    PHP实现mvc模式的思想
  • 原文地址:https://www.cnblogs.com/kkrisen/p/3518192.html
Copyright © 2011-2022 走看看