标签:log print for cst ems using next nbsp names
题目大意:
有一个序列,题目用n个整数组合 [ai,bi,ci]来描述它,[ai,bi,ci]表示在该序列中处于[ai,bi]这个区间的整数至少有ci个。如果存在这样的序列,请求出满足题目要求的最短的序列长度是多少。
思路:
设s[i]为从1~i的整数个数。
这样对于区间[ a , b]显然有 S[b+1] - S[a] >=c[i] (为什么是b+1?因为闭区间b也要选上呀)
然后还有
0<= S[B+1]-S[B] <=1 (整数的话最多比前一个大一,好吧,我大二- -|||我不二啊!!)
变形得:
S[B+1]-S[B] >=0
S[B]-S[B+1]>=-1
然后图就可以建立出来啦~~~~
1 #include<iostream> 2 #include<cstdio> 3 #include<algorithm> 4 #include<cstring> 5 #include<queue> 6 using namespace std; 7 #define maxn 50005 8 int head[maxn]; 9 struct edge{ 10 int next,to,w; 11 }e[maxn*3]; 12 int n,m,cnt,ans,l=0x7ffff,r; 13 int dis[maxn],cn[maxn]; 14 bool vis[maxn]; 15 void insert(int u,int v,int k){ 16 cnt++; 17 e[cnt].next=head[u];e[cnt].to=v;e[cnt].w=k; 18 head[u]=cnt; 19 } 20 void spfa(){ 21 queue<int> q; 22 memset(dis,-1,sizeof dis); 23 for(int i=l;i<=r;i++){ 24 vis[i]=1; 25 dis[i]=0; 26 q.push(i); 27 } 28 while(!q.empty()){ 29 int now=q.front(); 30 vis[now]=0;q.pop(); 31 for(int i=head[now];i;i=e[i].next){ 32 int s=e[i].to; 33 if(dis[s]<dis[now]+e[i].w) 34 { 35 dis[s]=dis[now]+e[i].w; 36 if(!vis[s]){ 37 vis[s]=1; 38 q.push(s); 39 } 40 } 41 } 42 } 43 } 44 int main(){ 45 while(~scanf("%d",&n)) 46 { 47 int a,b,c; 48 for(int i=1;i<=n;i++){ 49 scanf("%d%d%d",&a,&b,&c); 50 insert(a,b+1,c); 51 l=min(l,a); 52 r=max(r,b+1); 53 } 54 for(int i=l;i<=r;i++){ 55 insert(i,i+1,0); 56 insert(i+1,i,-1); 57 } 58 spfa(); 59 printf("%d",dis[r]); 60 } 61 }
标签:log print for cst ems using next nbsp names
原文地址:http://www.cnblogs.com/Elfish/p/7647299.html