标签:head 题目 scan 输出 技术分享 通过 lap sp1 堆栈
题意翻译 区间取数 题目描述 有n个区间,在区间[ai,bi]中至少取任意互不相同的ci个整数。求在满足n个区间的情况下,至少要取多少个正整数。 输入输出格式 输入格式 多组数据。 第一行的一个整数T表示数据个数。对于每组数据,第一行包含一个整数nn(11<=nn<=5000050000)表示区间数。以下nn行描述区间。输入的第(i+1)行包含三个整数ai,bi,ci,由空格分开。其中0<=ai<=bi<=50000,1<=ci<=bi-ai+1。 输出格式 对于每组数据,输出一个对于n个区间[ai,bi] 至少取ci个不同整数的数的总个数。 输入输出样例 输入样例#1: 1 5 3 7 3 8 10 3 6 8 1 1 3 1 10 11 1 输出样例#1: 6
这道题呢又是一个差分约束
很明显通过题意可以抽象出很多个b-(a-1)>=c
而且还有一点隐藏的东西1>=i-(i-1)>=0
转换一下下就是i-(i-1)>=0,i-(i-1)>=-1
因为是大于,所以差分的时候要跑最长路
再次记忆一下,b-a>=a,建a到b的单向边
然后堆栈spfa就能A了
代码
1 #include<cstdio> 2 #include<queue> 3 #include<cstring> 4 #define N 50011 5 using namespace std; 6 struct star{int to,nxt,val;}edge[10*N]; 7 int dis[N],head[N],stk[N],mi=0x7f7f7f7f,ma=-1; 8 int cnt=1,n,a,b,c,top,t; 9 bool in[N]; 10 inline void add(int u,int v,int w) 11 { 12 edge[cnt].nxt=head[u]; 13 edge[cnt].to=v; 14 edge[cnt].val=w; 15 head[u]=cnt++; 16 } 17 int main() 18 { 19 scanf("%d",&t); 20 while(t--) 21 { 22 memset(head,-1,sizeof(head)); 23 memset(dis,~0x7f,sizeof(dis)); 24 cnt=1; 25 scanf("%d",&n); 26 for(int i=1;i<=n;i++) 27 { 28 scanf("%d%d%d",&a,&b,&c); 29 add(a-1,b,c); 30 mi=min(a-1,mi); 31 ma=max(ma,b); 32 } 33 for(int i=mi;i<=ma;i++) 34 add(i,i-1,-1),add(i-1,i,0); 35 stk[++top]=mi; 36 dis[mi]=0,in[mi]=1; 37 while(top) 38 { 39 int now=stk[top--];in[now]=0; 40 for(int i=head[now];i!=-1;i=edge[i].nxt) 41 { 42 int to=edge[i].to; 43 if(dis[to]<dis[now]+edge[i].val) 44 { 45 dis[to]=dis[now]+edge[i].val; 46 if(!in[to]) 47 {stk[++top]=to;in[to]=1;} 48 } 49 } 50 } 51 printf("%d\n",dis[ma]); 52 } 53 return 0; 54 }
【差分约束】POJ1201/LG SP116 Intervals
标签:head 题目 scan 输出 技术分享 通过 lap sp1 堆栈
原文地址:https://www.cnblogs.com/Qin-Wei-Kai/p/10162372.html