差分约束非常好的题 poj 2983 spfa 为什么不加单源点会错 ,这道题后才是真正懂得差分约束真正怎么作。

 

开始一直没有检查出来错误,用 spfa ,在网上看别人也有类似的错。

分析题型,这是一个可能没有原点 ,的最短路, 可能图不是连通的。

spfa 判断差分约束的时候是单源的。

比如这组数据

6 6

V 2 5

V 1 3

V 2 3

P 6 2 5

V 2 6

V 5 5

分析发现 有 两个源,但是只能找到  1 的那个源, 2 6 那个是矛盾的 ,但是并不能找到,

所以spfa 是要确定 一个单源 ,这个源要到每一个点,这样才能保证算出每一个点的值。都符合条件,这个定值是一个单源。  这道题是有向图,可能走最短路的时候,没有一个可能到达所有点的源,可能无法判断其他的点是否满足条件。

 

差分约束应该是源要与其他的点都要有一条从源到其他点的有向边,这样才能通过源点这个定值确定其他的点是否满足这个差分约束不等式。

 

 

 

 

 

关于差分约束系统的可行解的问题:
判断没什么问题。反正都是用spfa或者bellman算法进行判断
但是关于可行解,最优解的问题有一两点值得思考:
比方说,d[0]=0.我要求所有的点的d[i]最大的情况下都可以满足差分约束条件。求出这组解。
那么我可以开始认为所有的点d[i]=inf。然后进行缩小,直到满足约束条件。这样求出的点由于是丛inf缩小的,必然是最大解
故为:
memset(d,inf,sizeof(d));
d[0]=0;
spfa() bellman()
if (d[j] > d[i] + w[i,j])
d[j] = d[i] + w[i,j];

反之,如果要求最小解的话,(即确定了d[0]=0的情况下每个点的d[i]尽可能的小)那么可以先把所有的点d[i]=-inf
然后扩大,直到满足约束条件,成为可行。因为我是“小心翼翼"的放大的,所以肯定是最小解

memset(d,-inf,sizeof(d))
d[0]=0;
spfa()   bellman()
if (d[j] < d[i] + w[i,j] )
d[j] = d[i] + w[i,j];


同时,建图的时候也有所不同:
求最大解的时候,是
b-a<=c
a -> b 权值w(a,b)=c

求最小解的时候,是
b-a>=c
a -> b 权值w(a,b)=c

你可能感兴趣的:(c,算法)