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; }