• King(国王)


    poj1364

    题目大意:给你n个数,组成一个集合s={a1,a2....an},再给你m个条件满足a[si]+a[si+1]...+a[si+ni] 后边一个关系,

    比如第一个条件是 a[1]+a[2]+a[3]>0然后转化为s[3]-s[0]>0>=1

    第二个条件是a[2]+a[3]+a[4]<2;转化为 s[4]-s[1]<2<=1

    这是做的第一道差分约束题,问了好几个同志,最终差不多了,就过了

    差分约束只是对于>= 或者<=使用,如果说求最大值的话,限制条件肯定是<=关系,然后建立图,求最短路径,找负环。相反的不说了。

    引用discuss里几句

    差分约束根本不需要什么附加顶点, 附加顶点的唯一
    用处就是保证图的连通性, 不让你有负环判不到的情况,

    解决这种问题的最佳途径就是初始把所有顶点都加入队列,
    并且将所有dis置0, 这就相当于加了一个不存在的附加顶点,
    它与所有的顶点的直连长度都是0,但是注意在判负环时必须是
    "cnt>n"而不是"cnt>=n", 因为第一次所有顶点入队只是相当于
    把一个附加顶点加入到队列中而已, 不应该算在cnt中, 如果在
    此步骤没有增加过cnt, 则">="也是可以的.

    解决:spfa,建图,本题根据建图不同求最短还是最长路也不一样,代码为求最短路,限制条件为<=

    #include <iostream>
    #include <queue>
    using namespace std;
    const int N=120;
    const int MAX=0x3f3f3f3f;
    struct node
    {
        int v,w,next;
    };
    node e[10000];
    int head[N];
    int dist[N];
    bool inq[N];
    int cnt[N];
    int n,m;
    int pos;
    void init()
    {
        for(int i=0;i<=n;i++)
        {//dist初始化为0,相当于添加一个超级源点n+1,到各个顶点的距离为0
            head[i]=-1;
            dist[i]=0;
            inq[i]=0;
            cnt[i]=0;
        }
        pos=0;
    }
    void addedge(int u,int v,int w)
    {
        e[pos].v=v;
        e[pos].w=w;
        e[pos].next=head[u];
        head[u]=pos++;
    }
    bool spfa()
    {
        queue<int> q;//将各个顶点入队
        for(int i=0;i<=n;i++)q.push(i);
        int v,w,v0;
        while(!q.empty())
        {
            v0=q.front();
            q.pop();
            inq[v0]=0;
            for(int i=head[v0];i!=-1;i=e[i].next)
            {
                v=e[i].v;
                w=e[i].w;
                if(dist[v0]+w<dist[v])
                {
                    dist[v]=dist[v0]+w;
                    if(!inq[v])
                    {
                        inq[v]=1;
                        q.push(v);//不能算第一个词入队,共有n+1个顶点所以判断条件为==n+1
                        if(++cnt[v] == n+1)return false;
                    }
                    
                }
            }
        }
        return true;
    }
    int main()
    {
        char cmp[5];
        int si,ni,k,i,j;
        while(scanf("%d",&n),n)
        {
           init();
           scanf("%d",&m);
           for(i=0;i<m;i++)
           {
                scanf("%d%d%s%d",&si,&ni,cmp,&k);
                if(cmp[0]=='g')
                    addedge(si+ni,si-1,-k-1);
                else 
                    addedge(si-1,si+ni,k-1);    
           }
           if(spfa())puts("lamentable kingdom");
              else puts("successful conspiracy");
        }
        system("pause");
        return 0;
    }
    

      

  • 相关阅读:
    由asp的一个错误,看语言的不同:asp & java
    chrome 显示图片遇到的问题,与 淘宝图片服务器 缓存 有关系
    asp 调用 vb(activex dll) ,参数传递(传引用)需要注意
    asp <----> vb(com,dll) <---> c 来回的调用,生命在于折腾
    HTTP/1.1 100 Continue
    java 线程栈 & java.lang.StackOverflowError
    硬盘分区的意义
    硬盘性能 & 文件碎片的一些思考
    Java并发——ReentrantLock类源码阅读
    使用Windows的NAT功能
  • 原文地址:https://www.cnblogs.com/hpustudent/p/2145958.html
Copyright © 2020-2023  润新知