[caioj]1400: 【模版】差分约束系统1:区间

来源:互联网 发布:linux操作vasp计算 编辑:程序博客网 时间:2024/06/07 06:15

题目描述
【题意】
给出n个区间,每个整数区间[ai,bi]中至少有ci个点。求整个区间中最少的点数。
【输入格式】
第一行:一个整数n,(1<=n<=50000)。
接下来n行每行三个整数ai,bi,ci,(0<=ai<=bi<=50000),(1<=ci<=bi-ai+1)。
【输出格式】
一个整数Z,表示整个区间中最少有多少个点。
【样例输入】
5
3 7 3
8 10 3
6 8 1
1 3 1
10 11 1
【样例输出】
6

话说差分约束系统以前就学过了。。
然而好像又忘得差不多。。
这题一眼就是统计前缀和,然后差分嘛
这题由于ai,bi的下界都是0,直接差分不方便,于是默认帮他ai++,bi++

推一下柿子:
f[bi]-f[ai]>=ci
f[bi]>=f[ai]+ci

然后对于相邻的两项
0<=f[x+1]-f[x]
f[x+1]>=f[x]+0

f[x]-f[x+1]>=-1
f[x]>=f[x+1]-1

于是跑最长路。。
于是最长路写挫了N发。。
最近不知道在干什么。。
于是感觉这题奥妙重重。。。。。
抄了一下fyc大佬的建图,后来发现最长路写挫了

#include<cstdio>#include<algorithm>#include<iostream>#include<cstring>#include<queue>using namespace std;const int N=50005;struct qq{    int x,y,z,last;}s[N*10];int num,last[N];void init (int x,int y,int z){    num++;    s[num].x=x;s[num].y=y;s[num].z=z;    s[num].last=last[x];    last[x]=num;}int f[N];int n,nn=0;bool in[N];void SPFA (){    queue<int> q;    memset(in,true,sizeof(in));    memset(f,-63,sizeof(f));    for (int u=0;u<=nn;u++) q.push(u);    f[0]=0;in[0]=true;    while (!q.empty())    {        int x=q.front();q.pop();        for (int u=last[x];u!=-1;u=s[u].last)        {            int y=s[u].y;            if (f[y]<f[x]+s[u].z)            {                f[y]=f[x]+s[u].z;                if (in[y]==false)                {                    in[y]=true;                    q.push(y);                }            }        }        in[x]=false;    }}int main(){    num=0;memset(last,-1,sizeof(last));    scanf("%d",&n);    for (int u=1;u<=n;u++)    {        int x,y,z;        scanf("%d%d%d",&x,&y,&z);        x++;y++;        init(x-1,y,z);        nn=max(nn,y);    }    for (int u=0;u<nn;u++)    {        init(u+1,u,-1);        init(u,u+1,0);    }    SPFA();    printf("%d\n",f[nn]);    return 0;}