1201

来源:互联网 发布:真假客服识别网站源码 编辑:程序博客网 时间:2024/04/29 16:21

 第一次做差分约束, 主要参考了这里和这里

求最小值时使之符合: dist[v] >= dist[u] + cost[u][v], 初值设为负无穷, 原点为0(不过这题我只初始化成了-1, 对于这题的dist[i]肯定是正数, -1算是下限了)

最大值时使之符合: dist[u] <= dist[v] - cost[u][v], 初值设为正无穷, 原点为0

这题还要考虑1>=s[i+1]-s[i]>=0....

#include <cstdio>#include <algorithm>using namespace std;const int MAX_SIZE = 50010;class sque{public:sque(): front(0), rear(0){};bool empty(){return front == rear;}bool enqueue(const int x){const int next = (rear + 1) % MAX_SIZE;if(next == front){return false;}mem[rear] = x;rear = next;return false;}bool dequeue(int &x){if(empty()){return false;}x = mem[front];front = (front + 1) % MAX_SIZE;return true;}private:int front, rear;int mem[MAX_SIZE];};struct edge{int vertex;int c;edge *next;};edge *g[MAX_SIZE];edge mem[10 * MAX_SIZE];int index, left = MAX_SIZE, right = -1, dist[MAX_SIZE];void input_build(){int n, a, b, c;scanf("%d", &n);for(int i = 0; i < n; ++i){scanf("%d%d%d", &a, &b, &c);left = min(left, a);right = max(b, right);edge *tmp = &mem[index];++index;tmp ->next = g[a];g[a] = tmp;tmp ->vertex = b + 1;tmp ->c = c;}++right;for(int i = left; i < right; ++i){edge *t1 = &mem[index];++index;t1 ->next = g[i];g[i] = t1;t1 ->vertex = i + 1;t1 ->c = 0;edge *t2 = &mem[index];++index;t2 ->next = g[i + 1];g[i + 1] = t2;t2 ->vertex = i;t2 ->c = -1;}}void spfa(){sque q;dist[left] = 0;for(int i = left + 1; i <= right; ++i){dist[i] = -1;}bool inque[MAX_SIZE] = {false};inque[left] = true;q.enqueue(left);while(!q.empty()){int u;q.dequeue(u);inque[u] = false;for(edge *p = g[u]; p; p = p ->next){if(dist[p ->vertex] < dist[u] + p ->c){dist[p ->vertex] = dist[u] + p ->c;if(!inque[p ->vertex]){inque[p ->vertex] = true;q.enqueue(p ->vertex);}}}}}int main(){input_build();spfa();printf("%d\n", dist[right]);return 0;}