zoukankan      html  css  js  c++  java
  • POJ1201 差分约束

    给定ai,bi, ci 表示区间[ai,bi]内至少有ci个点, 要求对于所有给定的ai,bi,ci,  至少多少个点才能满足题目的条件

    重做这一题学到的一点是, 可以设变量来表示一些东西,然后才能找出约束的条件,  s[i]表示区间0到i内有多少个点,  那么s[bi] - s[ai-1] >= ci 就是约束的条件

    当然了,也有隐藏的条件  1>= s[i] - s[i-1] >=0

    可以用最长路来求这一题,最短路当然也是可以的。

    #include <stdio.h>
    #include <string.h>
    #include <stdlib.h>
    #include <iostream>
    #include <queue>
    #include <stack>
    #include <vector>
    #include <map>
    #include <set>
    #include <string>
    #include <math.h>
    #pragma warning(disable:4996)
    #pragma comment(linker, "/STACK:1024000000,1024000000")
    typedef long long LL;      
    using namespace std;
    const int INF = 1<<30;
    const int N = 200000 + 10;
    struct Node
    {
        int to, dist, next;
        bool operator<(const Node&rhs)const
        {
            return dist < rhs.dist;
        }
    }g[N];
    int head[N], e;
    int dist[N];
    void addEdge(int a, int b, int c)
    {
        g[e].to = b;
        g[e].dist = c;
        g[e].next = head[a];
        head[a] = e++;
    }
    int dij(int x, int y)
    {
        priority_queue<Node> q;
        for (int i = x; i <= y; ++i)
            dist[i] = -INF;
        Node cur, tmp;
        dist[x] = cur.dist = 0;
        cur.to = x;
        q.push(cur);
        while (!q.empty())
        {
            cur = q.top(); q.pop();
            int u = cur.to;
            if (dist[u] > cur.dist)
                continue;
            for (int i = head[u]; i != -1; i = g[i].next)
            {
                int v = g[i].to;
                if (dist[v] < dist[u] + g[i].dist)
                {
                    tmp.dist = dist[v] = dist[u] + g[i].dist;
                    tmp.to = v;
                    q.push(tmp);
                }
            }
        }
        return dist[y];
    }
    int main()
    {
        int n, Min, Max, a, b, c;
        Node tmp;
        while (scanf("%d", &n) != EOF)
        {
            e = 0;
            memset(head, -1, sizeof(head));
            Min = INF, Max = -INF;
            for (int i = 1; i <= n; ++i)
            {
                scanf("%d%d%d", &a, &b, &c);
                a++;
                b++;
                Min = min(a - 1, Min);
                Max = max(b, Max);
                addEdge(a - 1, b, c);
            }
            for (int i = Min+1; i <= Max; ++i)
            {
                addEdge(i - 1, i, 0);
                addEdge(i, i - 1, -1);
                
            }
            printf("%d
    ", dij(Min, Max));
        }
        return 0;
    }
  • 相关阅读:
    GC选择之CMS 并发标记清除
    JVM内存概览与GC初步
    Shell 判断语句
    SUID SGID
    maven package
    ACL权限控制列表
    账户与密码管理
    Ubuntu与Centos在登陆安全方面的比较
    【PL/SQL Developer】动态执行表不可访问,本会话的自动统计被禁止
    【Centos7】Delete virtual bridge
  • 原文地址:https://www.cnblogs.com/justPassBy/p/4647312.html
Copyright © 2011-2022 走看看