题目:http://acm.hdu.edu.cn/showproblem.php?pid=1534
题目大意:一个工程被分为若干个部分,每个部分被完成都需要一定的时间,给定工程若干部分间开始或结束的先后关系,要求在最少的时间内完成工程。若能完成,输出每个部分开始的时间,如果不能,输出impossible。
考查点:差分约束系统
思路:工程间的关系有四种,FAS, SAF, FAF, SAS。
始时间。Time[i]表示i需要花费的时间。 则四种关系便可化解为一些表达式
表达式关系,并且题目是要求工程尽量早的完成,既求每个部分的最早开始时间,因
为开始的越早,整个工程就会结束的越早,因此进一步化解等式:
Start[x] >= start[y] - time[x];
Start[x] >= start[y] + time[y];
Start[x] >= start[y] + time[y] – time[x];
Start[x] >= start[y] + 0;
为每一个start求一个下界。分析到这一步,用脚后跟都能想到可以用差分约束系统
来搞此题。
差分约束系统是通过解最短路或最长路来实现的。此题求的是每个start的下界,故
我们用求最长路的方法(d[u] < d[v] + (u,v))
这样我们每个表达式可统一为start[x] >= start[y] + c 的形式
条长为c的边即可。
个start为零即可,但是这样做把算法改为SPFA就不对了,这是为什么呢?我们来看
这样一组数据,
2
1
2
SAF 1 2
#
正确的输出应该是
1 2
2 0
但是如果直接用SPFA的话,结果是
1 0
2 0
问题出在初始化上,用bellman时,算法本身会扫描每一条边,因此没有所谓的出发
点,但是SPFA不同,SPFA是由一个最初始的点开始拓展的。如果我们从1开始,那
么,2根本就不会被扩展到。而且有1开始扩展是没有理由的,因为体力没有告诉你
1肯定最先开始,这个用例就是2先开始的,如何纠正这个错误,这就用到了类似于
网络流里加源点的思想。我们加一个点只想每一个部分,边权为0,这样的话,初始
化start为-maxlongint
会出现之前的情况了
提交情况: wrong answer 无数次
收获: 对差分约束系统的题分析上有了进一步的认识。也对建图有一定的感悟了
经验: 一定要分析各种情况,不能妄下结论,不能心浮气躁,冲动是魔鬼
//AC code
#include <stdio.h>
#include <string.h>
#define MAXN 10000
#define MAXM 10000000
#define INF 2100000000
struct NODE{
};
NODE edges[MAXM];
long ad;
long point[MAXN];
long time[MAXN], start[MAXN];
int SPFA(long n){
}
int main(){
}