差分约束系统:有一组或多组Xj-Xi<=Bk的不等式。看到这个不等式我们很容易想到在最短路中的松弛方程dis[v]<dis[u]+cost[i],由此想到可以利用图论的知识来解决差分约束的问题,从i到j建立一条权值为Bk的边,利用spfa来解决问题。我不是很理解dis[]里存的是什么,但是初步理解为解的个数。
题意:构造一个集合,这个集合内的数字满足所给的n个条件,每个条件都是指在[a,b]内至少有c个数在集合内。
为了构造不等式,我们假设Ti表示[0,i-1]区间内,要选多少个数,这样就形成了三个约束条件。
Tb+1-Ta>=C, 0=<Ti-Ti-1<=1
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
const int oo=1e8;
const int mn=50010;
const int mm=500100;
int edge,minn,maxx;
int ver[mm],next[mm],cost[mm];
int head[mn],vis[mn],dis[mn],q[mn];
void addedge(int u,int v,int c)
{
ver[edge]=v,cost[edge]=c,next[edge]=head[u],head[u]=edge++;
}
bool spfa()
{
int i,u,v,l,r=0,tmp;
for(i=minn;i<=maxx;i++) dis[i]=-oo,vis[i]=0;
dis[q[r++]=minn]=0;
for(l=0;l!=r;(++l>mn)?l=0:l)
for(i=head[u=q[l]],vis[u]=0;i>=0;i=next[i])
if(dis[v=ver[i]]<(tmp=dis[u]+cost[i]))
{
dis[v]=tmp;
if(vis[v]) continue;
vis[q[r++]=v]=1;
if(r>=mn) r=0;
}
for(i=minn;i<=maxx;i++)
printf("%d\n",dis[i]);
}
int main()
{
int n,i,j,a,b,c;
while(~scanf("%d",&n))
{
memset(head,-1,sizeof(head));
edge=0;
minn=oo,maxx=-1;
for(i=1;i<=n;i++)
{
scanf("%d%d%d",&a,&b,&c);
if(a<minn) minn=a;
if(b+1>maxx) maxx=b+1;
addedge(a,b+1,c);
}
for(i=minn;i<=maxx;i++)
{
addedge(i,i-1,-1);
addedge(i-1,i,0);
}
spfa();
}
return 0;
}