zoukankan      html  css  js  c++  java
  • 种树-洛谷P1250(差分约束)

    传送门

    令前缀和为s[i],则⼀一个要求等价于 s[r] - s[l - 1] >= x。

    题中还有别的要求,包括 s[i] - s[i - 1] <= 1 和 s[i] - s[i- 1] >= 0。

    建一个超级原点s,把所有结点连到s(令s = n + 1)

    差分约束系统规定的只是元素的相对关系

    按照题意,相对关系不变时最后的答案尽可能小

    因此最终答案应该是:dis[ n ] - min_dis

    #include<cstdio>
    #include<cstring>
    #include<queue>
    #include<algorithm>
    using namespace std;
    
    inline int read()
    {
        int sum = 0,p = 1;
        char ch = getchar();
        while(ch < '0' || ch > '9')
        {
            if(ch == '-')
                p = -1;
            ch = getchar();
        }
        while(ch >= '0' && ch <= '9')
        {
            (sum *= 10) += ch - '0';
            ch = getchar();
        }
        return sum * p;
    }
    
    const int maxn = 30005,maxm = 5005;
    int n,m,s,cnt;
    int dis[maxn],head[maxn];
    bool vis[maxn];
    struct edge
    {
        int nxt,to,wei;
    } e[maxn * 5];
    
    void add(int x,int y,int z)
    {
        e[++cnt].nxt = head[x];
        e[cnt].to = y;
        e[cnt].wei = z;
        head[x] = cnt;
    }
    
    void spfa(int x)
    {
        queue<int> q;
        q.push(x);
        for(int i = 0; i <= n + 1; i ++)
            dis[i] = 1e9;
        dis[s] = 0;
        vis[s] = true;
        while(!q.empty())
        {
            int o = q.front();
            q.pop();
            vis[o] = false;
            for(int i = head[o]; i; i = e[i].nxt)
            {
                int v = e[i].to;
                if(dis[v] > dis[o] + e[i].wei)
                {
                    dis[v] = dis[o]  + e[i].wei;
                    if(!vis[v])
                    {
                        q.push(v);
                        vis[v] = true;
                    }
                }
            }
        }
    }
    
    int main()
    {
        n = read(),m = read();
        s = n + 1;
        memset(head,-1,sizeof(head));
        for(int i = 0; i <= n; i++)
            add(s,i,0);
        int a,b,c;
        for(int i = 1; i <= m; i++)
        {
            a = read(),b = read(),c = read();
            add(b,a - 1,-c);
        }
        for(int i = 1; i <= n; i++)
        {
            add(i - 1,i,1);
            add(i,i - 1,0);
        }
        spfa(s);
        int ans = 1e9;
        for(int i=0; i<=n; i++)
             ans = min(ans, dis[i]);
        printf("%d",dis[n] - ans);
        return 0;
    }
  • 相关阅读:
    Linux登录出现modle is unknow
    django表单
    django中的站点管理
    ubuntu apache2服务器配置
    django安装和卸载
    Eclipse新版 syso无法自动补全的解决方法
    jetty启动报错Unsupported major.minor version 51.0
    Sencha Touch2 时间轴ListPanel
    使用css3伪元素制作时间轴并且实现鼠标选中高亮效果
    JAVA数据结构系列 栈
  • 原文地址:https://www.cnblogs.com/darlingroot/p/11221586.html
Copyright © 2011-2022 走看看