poj 1201 Intervals & 1716 Integer Intervals 差分约束
题目是求一个序列,要满足给定条件,求它的最少个数
设d[i]为在[0, i)区间内答案的个数,其中d[0] = 0
则对题目输入的a, b ,c有:d[b+1] – d[a] >= c
题意隐藏的不等式有: 0 <= d[i+1] – d[i] <= 1, d[i] – d[0] >= 0
因为是求最少个数,所以 以0为源点求最长路,答案就为d[n] – d[1]
1716,则把上面的c改为2即可
#include <iostream> #include <vector> #include <queue> #include <cstring> #include <cstdio> using namespace std; const int MAX = 50005; const int INF = 1000000000; struct edge { int v; int cost; edge(){} edge(int v, int cost) { this->v = v; this->cost = cost; } }; vector<edge> adj[MAX]; queue<int> Q; bool is_in_queue[MAX]; int dis[MAX]; int _min, _max; int n; int cnt[MAX]; void spfa() { while (!Q.empty()) Q.pop(); int u; Q.push(_min); memset(is_in_queue, false, sizeof(is_in_queue)); for (int i = _min; i <= _max+1; i++) dis[i] = -INF; dis[_min] = 0; is_in_queue[_min] = true; while (!Q.empty()) { u = Q.front(); Q.pop(); is_in_queue[u] = false; for (int i = 0; i < adj[u].size(); i++) { int v = adj[u][i].v; int w = adj[u][i].cost; if (dis[v] < dis[u] + w) { dis[v] = dis[u]+w; if (!is_in_queue[v]) { Q.push(v); is_in_queue[v] = true; } } } } } int main() { int a, b, c; while (cin >> n) { _min = INF; _max = -1; for (int i = 0; i < n; i++) { scanf("%d%d%d", &a, &b, &c); adj[a].push_back(edge(b+1, c)); _min = min(_min, a); _max = max(_max, b); } for (int i = _min; i <= _max; i++) { adj[0].push_back(edge(i, 0)); adj[i].push_back(edge(i+1, 0)); adj[i+1].push_back(edge(i, -1)); } adj[0].push_back(edge(_max+1, 0)); spfa(); cout << dis[_max+1] - dis[_min] << endl; for (int i = 0; i <= _max+1; i++) adj[i].clear(); } return 0; }