POJ 1201 Intervals

题意:给出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;
}

  

原文地址:https://www.cnblogs.com/Apro/p/4904304.html