{二维spfa}
1 program sky;{由于编辑器导致的格式问题请多包涵}
2 const
3 maxn = 100000;
4 type
5 rec = record
6 y,w,ww,z,next : longint;
7 end;
8 var
9 x,y,z,w,ww,n,m : longint;
10 i,e,tp,tpp : longint;
11 bian,jia,h,t : longint;
12 q : array[0..maxn+1,1..2] of longint;
13 v : array[0..11,0..1025] of boolean;
14 a : array[0..100] of rec;
15 f : array[0..11] of longint;
16 dis : array[0..11,0..1025] of longint;
17 ans : longint;
18
19 function pd(aa,bb :longint ):boolean;{第一次打位运算处理状态,判断是否走过bb结点}
20 begin
21 if (1<<(aa-1) and bb)<>0 then exit(true);
22 exit(false);
23 end; { pd }
24 function change(aa,bb :longint ):longint;{走过a[e].y这个结点}
25 begin
26 change:=1<<(aa-1) or bb;
27 end;
28 procedure spfa;
29 begin
30 fillchar(dis,sizeof(dis),63);
31 dis[1,1]:=0;
32 h:=1; t:=1;
33 q[1,1]:=1; q[1,2]:=1; v[1,1]:=true;
34 while h<>t+1 do
35 begin
36 e:=f[q[h,1]];
37 tp:=q[h,1]; tpp:=q[h,2];
38 inc(h);if h=maxn then h:=1;
39 while e<>0 do
40 begin
41 if pd(a[e].z,tpp) then{打的有点小麻烦了,bian不用放在里面}
42 begin
43 bian:=change(a[e].y,tpp);
44 jia:=a[e].w;
45 end else
46 begin
47 bian:=change(a[e].y,tpp);{change是加上a[e].y这个点,不是a[e].z......,并且两种情况都要变}
48 jia:=a[e].ww;
49 end;
50 if dis[tp,tpp]+jia<dis[a[e].y,bian] then{仿照一维的spfa,把状态弄进去}
51 begin
52 dis[a[e].y,bian]:=dis[tp,tpp]+jia;
53 if not v[a[e].y,bian] then{需要改变的不仅有dis而且有v,q}
54 begin
55 v[a[e].y,bian]:=true;
56 inc(t); if t=maxn then t:=1;
57 q[t,1]:=a[e].y; q[t,2]:=bian;{1存结点,2存状态,用2进制表示}
58 end;
59 end;
60 e:=a[e].next;
61 end;
62 v[tp,tpp]:=false;
63 end;
64 end;
65 begin
66 readln(n,m);
67 for i:=1 to m do
68 begin
69 read(x,y,z,w,ww);
70 inc(e);
71 a[e].y:=y; a[e].z:=z;
72 a[e].w:=w; a[e].ww:=ww; a[e].next:=f[x];
73 f[x]:=e;
74 end;
75 spfa;
76 ans:=maxlongint>>2;
77 for i:=0 to 1<<n-1 do{0到1<<n-1为所有状态}
78 if ans>dis[n,i] then ans:=dis[n,i];
79 if ans=maxlongint>>2 then writeln('impossible'){竟然没看见impossible……这种情况}
80 else writeln(ans);{也注意赋的初值,maxlongint>>1是比fillchar63大的,所以div4来判断是否未被更新}
81 end.
skysun原创。转载请注明出处。http://www.cnblogs.com/skysun