题目链接:http://cstest.scu.edu.cn/soj/problem.action?id=1687
题目大意:
在区间[0,50000]上面有一些整数点。
现给出50000个区间。
并给出每个区间至少应覆盖多少个点。
问这个区间上总共至少有多少个点
算法:
首先声明我完完全全不知道当时的我为毛线要倒着建图。
好吧,当时我是用s[i]表示[i,50000]区间上取了多少个点
如果某个线段[a,b]覆盖了c个点的话,那么就建一条从b到a+1的边,权值为c。
当然隐含条件是任何一个区间包含的点数不可能大于区间长度+1,当然包含的点数也不会是负数。
代码如下:
#include<stdio.h> #include<string.h> int head[50005],Q[50005],inq[50005],d[50005],hash[50005],E; typedef struct { int u,v,w,nxt; } EDGE; EDGE edge[200000]; void addedge(int u,int v,int w) { edge[E].u=u; edge[E].v=v; edge[E].w=w; edge[E].nxt=head[u]; head[u]=E++; } int main() { int n,i,u,v,w,pre,front,rear; while(~scanf("%d",&n)) { memset(head,-1,sizeof(head)); memset(d,-1,sizeof(d)); memset(inq,0,sizeof(inq)); memset(hash,0,sizeof(hash)); hash[0]=hash[50002]=1; pre=0; E=0; for(i=0; i<n; i++) { scanf("%d%d%d",&u,&v,&w); addedge(u,v+1,w); hash[u]=hash[v+1]=1; } for(i=1; i<=50002; i++) { if(hash[i]) { addedge(i,pre,pre-i); addedge(pre,i,0); pre=i; } } front=rear=0; Q[rear++]=0; inq[0]=1; d[0]=0; while(front!=rear) { u=Q[front++]; front%=50005; inq[u]=0; for(i=head[u]; i!=-1; i=edge[i].nxt) { v=edge[i].v; if(d[v]<d[u]+edge[i].w) { d[v]=d[u]+edge[i].w; if(!inq[v]) { Q[rear++]=v; rear%=50005; inq[v]=1; } } } } printf("%d\n",d[50002]); } return 0; }