给定一个图,N个顶点,M条边,N值极小,对于每一条边,有ai,bi,ci,pi,ri这几个参数,表示这条边从ai到bi,如果之前经过了ci,那么费用是pi,否则费用为ri,求从1到N的最小费用。
用f[i,j]为节点,i表示当前在哪个点,j转化为二进制数后为0位表示未经过这一点,为1这表示经过了这一点,进行SPFA即可
{对j的解释,11:1011,表示经过1,3,4这三个点而没有经过2}
View Code
1 program pku3411(input,output);
2 type
3 node = ^link;
4 link = record
5 goal,ci,pi,wi : integer;
6 next : node;
7 end;
8 node2 = record
9 state,now : longint;
10 end;
11 var
12 l : array[0..11] of node;
13 d : array[0..11,0..1024] of longint;
14 v : array[0..11,0..1024] of boolean;
15 q : array[0..20000] of node2;
16 n,m : longint;
17 procedure add(xx,yy,cc,ww,pp: longint );
18 var
19 t : node;
20 begin
21 new(t);
22 t^.goal:=yy;
23 t^.ci:=cc;
24 t^.wi:=ww;
25 t^.pi:=pp;
26 t^.next:=l[xx];
27 l[xx]:=t;
28 end; { add }
29 procedure init;
30 var
31 i,xx,yy,cc,pp,ww : longint;
32 begin
33 readln(n,m);
34 for i:=1 to n do
35 l[i]:=nil;
36 for i:=1 to m do
37 begin
38 readln(xx,yy,cc,ww,pp);
39 add(xx,yy,cc,ww,pp);
40 end;
41 end; { init }
42 procedure spfa();
43 var
44 head,tail : longint;
45 newstate : node2;
46 t : node;
47 begin
48 head:=0;
49 tail:=1;
50 q[1].now:=1;
51 q[1].state:=1;
52 fillchar(v,sizeof(v),false);
53 fillchar(d,sizeof(d),63);
54 d[1,1]:=0;
55 v[1,1]:=true;
56 while head<tail do
57 begin
58 inc(head);
59 v[q[head].now,q[head].state]:=false;
60 t:=l[q[head].now];
61 while t<>nil do
62 begin
63 if (q[head].state)and(1<<(t^.ci-1))>0 then
64 begin
65 newstate.now:=t^.goal;
66 newstate.state:=(q[head].state)or(1<<(t^.goal-1));
67 if d[q[head].now,q[head].state]+t^.wi<d[newstate.now,newstate.state] then
68 begin
69 d[newstate.now,newstate.state]:=d[q[head].now,q[head].state]+t^.wi;
70 if not v[newstate.now,newstate.state] then
71 begin
72 inc(tail);
73 q[tail]:=newstate;
74 v[newstate.now,newstate.state]:=true;
75 end;
76 end;
77 end
78 else
79 begin
80 newstate.now:=t^.goal;
81 newstate.state:=(q[head].state)or(1<<(t^.goal-1));
82 if d[q[head].now,q[head].state]+t^.pi<d[newstate.now,newstate.state] then
83 begin
84 d[newstate.now,newstate.state]:=d[q[head].now,q[head].state]+t^.pi;
85 if not v[newstate.now,newstate.state] then
86 begin
87 inc(tail);
88 q[tail]:=newstate;
89 v[newstate.now,newstate.state]:=true;
90 end;
91 end;
92 end;
93 t:=t^.next;
94 end;
95 end;
96 end; { spfa }
97 procedure print;
98 var
99 i,answer : longint;
100 begin
101 answer:=maxlongint;
102 for i:=0 to 1024 do
103 if d[n,i]<answer then
104 answer:=d[n,i];
105 if answer<19950714 then
106 writeln(answer)
107 else
108 writeln('impossible');
109 end; { print }
110 begin
111 init;
112 spfa;
113 print;
114 end.