题意:给出n个区间li, ri, ci,求一个集合,表示在区间li到ri之间至少要有ci个元素在集合中。
解法:差分约束系统。解法大概跟POJ1716一样,就是数据量看着比较大……最后写了个spfa……用的小红书模板……那个模板有点坑……必须反着建边……
代码:
#include<stdio.h> #include<iostream> #include<algorithm> #include<string> #include<string.h> #include<math.h> #include<limits.h> #include<time.h> #include<stdlib.h> #include<map> #include<queue> #include<set> #include<stack> #include<vector> #include<iomanip> #define LL long long #define lson l, m, rt << 1 #define rson m + 1, r, rt << 1 | 1 using namespace std; const int maxn = 50010; int n, m, src; vector <pair<int, int> > g[maxn]; int dist[maxn]; bool inQue[maxn]; queue <int> que; void spfa() { memset(dist, 63, sizeof(dist)); dist[src] = 0; while(!que.empty()) que.pop(); que.push(src); inQue[src] = true; while(!que.empty()) { int u = que.front(); que.pop(); for(int i = 0; i < g[u].size(); i++) if(dist[u] + g[u][i].second < dist[g[u][i].first]) { dist[g[u][i].first] = dist[u] + g[u][i].second; if(!inQue[g[u][i].first]) { inQue[g[u][i].first] = true; que.push(g[u][i].first); } } inQue[u] = false; } } int main() { while(~scanf("%d", &n)) { src = maxn - 1; int mn = 0; for(int i = 0; i < maxn; i++) g[i].clear(); for(int i = 0; i < n; i++) { int a, b, c; scanf("%d%d%d", &a, &b, &c); g[a].push_back(make_pair(b + 1, -c)); src = min(src, a); mn = max(mn, b + 1); } for(int i = src + 1; i <= mn; i++) { g[i - 1].push_back(make_pair(i, 0)); g[i].push_back(make_pair(i - 1, 1)); } spfa(); cout << dist[src] - dist[mn] << endl; } return 0; }