题目链接: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,当然包含的点数也不会是负数。
然后跑最短路。
PS:妈蛋,我自己今年寒假写的代码都看了半天才看懂。。。。可见及时写解题报告有多重要。。。T^T
代码如下:
#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;
}