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\n", dij(Min, Max));

    }

    return 0;

}

 

你可能感兴趣的:(差分约束)