Time Limit: 2000MS | Memory Limit: 65536K | |
Total Submissions: 24152 | Accepted: 9186 |
Description
Input
Output
Sample Input
5 3 7 3 8 10 3 6 8 1 1 3 1 10 11 1
Sample Output
6
题解:差分约束系统。
之前提到过一道差分约束系统的题,说是用到了树状数组的思想。这道题也是一样的道理。每个点表示的是从开始到当前点中选定的数量。
一般的的差分约束系统的题都是要求 u-v<=x 可以转成u<=v+x的形式,最终通过最短路求解。
而这道题有点不同,他要求的是区间中的数量大于等于某值,即 [x,y] >=z y-(x-1)>=z y>=(x-1)+z 由(x-1)向y连边,然后跑最长路即可。另外主要这道题有一个隐藏条件,就是相邻的两个点记录的值的差应该是大于等于0,小于等于1的。
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #include<queue> using namespace std; int n,m; int point[1000003],v[1000003],c[1000003],next[1000003],tot=0,dis[1000003],maxn=0,can[1000003]; void add(int x,int y,int z) { tot++; next[tot]=point[x]; point[x]=tot; v[tot]=y; c[tot]=z; } void spfa() { queue<int> p; p.push(0); can[0]=1; while (!p.empty()) { int now=p.front(); p.pop(); for (int i=point[now];i;i=next[i]) if (dis[v[i]]<dis[now]+c[i]) { dis[v[i]]=dis[now]+c[i]; if (!can[v[i]]) { can[v[i]]=1; p.push(v[i]); } } can[now]=0; } } int main() { scanf("%d",&n); for (int i=1;i<=n;i++) { int x,y,z; scanf("%d%d%d",&x,&y,&z); add(x,y+1,z); maxn=max(maxn,y+1); } for (int i=0;i<maxn;i++) { add(i,i+1,0); add(i+1,i,-1); } memset(dis,128,sizeof(dis)); dis[0]=0; spfa(); cout<<dis[maxn]<<endl; return 0; }