• poj1364 King(差分约束)


    题目链接

    简介:
    给出若干形如
    a(si) + a(si+1) + … + a(si+ni) < ki
    a(si) + a(si+1) + … + a(si+ni) > ki
    的不等式,询问是否存在合法的a序列

    分析:
    柿子都是区间和的形式
    这就在提醒我们把区间和变成前缀和的差
    比如说不等式
    a(si) + a(si+1) + … + a(si+ni) < ki
    a(si) + a(si+1) + … + a(si+ni) > ki
    我们可以转化为
    sum(si+ni)-sum(si-1) <= ki-1
    sum(si-1)-sum(si+ni) <= -ki-1

    这样就完全符合差分约束的形式了
    我们还是用Bellman判负环的方法求解就好了

    tip

    注意结点数目
    在判断负环的时候,最规范的写法是

    ++cnt>(n+1)

    因为一共有n+1个结点(0~n)

    //这里写代码片
    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<vector>
    #include<algorithm>
    #include<queue>
    
    using namespace std;
    
    const int N=203;
    int n,m;
    
    struct node{
        int x,y,v;
    };
    
    struct Bellman{
        int n,m;
        vector<node> e;
        vector<int> G[N];
        bool in[N];
        int cnt[N];
        int dis[N];
        int pre[N];
    
        void init(int n)
        {
            this->n=n;
            e.clear();
            for (int i=0;i<=n;i++) G[i].clear();
        }
    
        void add(int u,int w,int z)
        {
            e.push_back((node){u,w,z});
            m=e.size();
            G[u].push_back(m-1);
        }
    
        bool fuhuan()
        {
            memset(in,0,sizeof(in));
            memset(cnt,0,sizeof(cnt));
            queue<int> Q;
            for (int i=0;i<=n;i++)
            {
                in[i]=1; dis[i]=0;
                Q.push(i);
            }
    
            while (!Q.empty())
            {
                int now=Q.front(); Q.pop();
                in[now]=0;
    
                for (int i=0;i<G[now].size();i++)
                {
                    node way=e[G[now][i]];
                    if (dis[way.y]>dis[now]+way.v)
                    {
                        dis[way.y]=dis[now]+way.v;
                        pre[way.y]=G[now][i];
                        if (!in[way.y])
                        {
                            in[way.y]=1;
                            Q.push(way.y);
                            if (++cnt[way.y]>(n+1)) return 1;
                        }
                    }
                }
            }
            return 0;
        }
    };
    Bellman A;
    
    int main()
    {
        while (scanf("%d%d",&n,&m)==2)
        {
            A.init(n);
            char opt[5];
            for (int i=1;i<=m;i++)
            {
                int u,w,z;
                scanf("%d%d%s%d",&u,&w,&opt,&z);
                w+=u,u--;
                if (opt[0]=='g')   //>
                {
                    A.add(w,u,-z-1);
                }
                else
                {
                    A.add(u,w,z-1);
                }
            }
    
            if (A.fuhuan())          //无解 
                printf("successful conspiracy
    ");
            else printf("lamentable kingdom
    ");
        }
    }
  • 相关阅读:
    校验参考相关备份
    API接口设计
    redis 基础配置
    Apollo 统一配置中心
    http返回状态码记录
    ngnix实战
    OAuth2三方授权
    OAuth2授权协议记录
    KMP算法
    分治法
  • 原文地址:https://www.cnblogs.com/wutongtong3117/p/7673053.html
Copyright © 2020-2023  润新知