题目大意:有一个序列,题目用n个整数组合 [ai,bi,ci]来描述它,[ai,bi,ci]表示在该序列中处于[ai,bi]这个区间的整数至少有ci个。如果存在这样的序列,请求出满足题目要求的最短的序列长度是多少。如果不存在则输出 -1。
题目分析:显然差分约束+spfa、其实这题我理解也不怎么深……不晓得差分约束怎么会和spfa结合起来。
代码:
#define init(a,what) memset(a,what,sizeof(a))
#define read freopen("zx.in","r",stdin)
#define write freopen("zx.out","w",stdout)
const int INF=0x3f3f3f3f;
const int MAXN=50000+10;
typedef struct
{
int num,p;
}ZX;
ZX zx;
vector<ZX>map[MAXN];
int nnum,minn,maxn,dist[MAXN];
bool vis[MAXN];
void spfa()
{
queue<int>q;
init(vis,false);
for(int i=minn;i<=maxn;i++) dist[i]=(i==minn ? 0 : -INF);
vis[minn]=true;
q.push(minn);
while(!q.empty())
{
int xx=q.front();
q.pop();
vis[xx]=false;
int curlen=map[xx].size();
for(int i=0;i<curlen;i++)
{
if(dist[map[xx][i].p]<dist[xx]+map[xx][i].num)
{
dist[map[xx][i].p]=dist[xx]+map[xx][i].num;
if(!vis[map[xx][i].p])
{
vis[map[xx][i].p]=true; q.push(map[xx][i].p);
}
}
}
}
}
int main()
{
read, write;
int a,b,c;
while(scanf("%d",&nnum)!=EOF)
{
minn=INF, maxn=-1;
for(int i=1;i<=nnum;i++)
{
scanf("%d%d%d",&a,&b,&c);
if(a<minn) minn=a;
if(b+1>maxn) maxn=b+1;
zx.num=c, zx.p=b+1;
map[a].push_back(zx);
}
for(int i=minn;i<=maxn;i++)
{
zx.num=0, zx.p=i+1;
map[i].push_back(zx);
zx.num=-1, zx.p=i;
map[i+1].push_back(zx);
}
spfa();
printf("%d/n",dist[b]);
}
return 0;
}