悲剧的比赛过后,觉得自己有必要学习一下差分约束系统,看了一下,有好多熟悉的影子,线性规划,网络流,最短路,算是算法的相通性吧。差分约束系统关键是建立数学模型,模型建立对了后面的就简单了!对于他的原理,我就不在赘述了,随便一搜好几页。
对于用差分系统求最优解的问题,我还是不太明白,我承认我很笨,呵呵!对于已建好的模型,源点以右的可行解(假设有可行解)是最大可行解,以左是最小可行解,因为建图的时候所用的三角不等式我们习惯把最大约束条件建成往右的边,最小约束条件建成往左的边,因为有可行解(如果同一位置的最大约束条件小于最小约束条件,那么差分约束系统是不成立的),所以求最短路的时候往右是最大约束条件优先,往左是最小约束条件优先,就形成了上面所说的结果!
用pku 1364小试了把牛刀(赤裸裸的差分约束啊),结果悲剧的错了半个下午,(额。。。。。好吧,我承认做题的时候看电影是我的不对,不过暮色真的挺不错的,推荐!),结果电影看完以后发现看错题了,稍微改动一下就A了!spfa+stack,其实很水的一道题!
1 #include < stdio.h >
2 #include < string .h >
3 #include < stdlib.h >
4 #define MAX 105
5 typedef struct adj{
6 int reach,v;
7 adj * next;
8 } adj;
9 typedef struct point{
10 adj * visit;
11 } point;
12 int n,m; point h[MAX];
13 void add( int x, int y, int v)
14 {
15 adj * p; p = (adj * )malloc( sizeof (adj));
16 p -> reach = y; p -> v = v;
17 p -> next = h[x].visit; h[x].visit = p;
18 }
19 int spfa()
20 {
21 int s[MAX],dis[MAX],cnt[MAX],top = 0 ,i; bool visit[MAX];
22 memset(cnt, 0 , sizeof (cnt));
23 for (i = 0 ; i <= n; i ++ ) {s[top ++ ] = i;dis[i] = 0 ; cnt[i] ++ ; visit[i] = true ;}
24 while (top){
25 int t = s[ -- top]; visit[t] = false ; adj * p = h[t].visit;
26 while (p != NULL){
27 int r = p -> reach, v = p -> v;
28 if (dis[r] > dis[t] + v){
29 dis[r] = dis[t] + v;
30 if (visit[r] == false ){
31 s[top ++ ] = r; visit[r] = true ;cnt[r] ++ ;
32 if (cnt[r] > n + 10 ) return - 1 ;
33 }
34 }
35 p = p -> next;
36 }
37 }
38 return 0 ;
39 }
40 void sodc()
41 {
42 int ans = spfa();
43 if (ans == - 1 ) printf ( " successful conspiracy\n " );
44 else printf ( " lamentable kingdom\n " );
45 }
46 int main()
47 {
48 int i,x,y,v,t;
49 while (scanf ( " %d " , & n) && n){
50 for (i = 0 ; i <= n; i ++ ) h[i].visit = NULL;
51 scanf ( " %d " , & m);
52 for (i = 0 ; i < m; i ++ ){
53 char str[ 5 ]; memset(str, 0 , sizeof (str));
54 scanf ( " %d%d%s%d " , & x, & y, & str, & v);
55 if (str[ 0 ] == ' g ' ) add(x + y,x - 1 , - (v + 1 ));
56 else add(x - 1 ,y + x,v - 1 );
57 }
58 sodc();
59 }
60 return 0 ;
61 }
62