【题目描述】
你赢得了一场航空公司举办的比赛,奖品是一张加拿大环游机票。旅行在这家航空公司开放的最西边的城市开始,然后一直自西向东旅行,直到你到达最东边的城市,再由东向西返回,直到你回到开始的城市。除了旅行开始的城市之外,每个城市只能访问一次,因为开始的城市必定要被访问两次(在旅行的开始和结束)。
当然不允许使用其他公司的航线或者用其他的交通工具。
给出这个航空公司开放的城市的列表,和两两城市之间的直达航线列表。找出能够访问尽可能多的城市的路线,这条路线必须满足上述条件,也就是从列表中的第一个城市开始旅行,访问到列表中最后一个城市之后再返回第一个城市。
【解题报告】
双进程DP
1 {
2 ID:wwzhwdw1
3 PROG:tour
4 LANG:PASCAL
5 }
6
7 program tour;
8 var
9 t1,t2,k,j,maxn,i,n,m,t:longint;
10 s,s1,s2:string;
11 name:array[0..101]of string;
12 a:array[0..101,0..101]of boolean;
13 f:array[0..101,0..101]of longint;
14
15 procedure init;
16 begin
17 assign(input,'tour.in');
18 reset(input);
19 assign(output,'tour.out');
20 rewrite(output);
21 end;
22
23 procedure outit;
24 begin
25 close(input);
26 close(output);
27 end;
28
29 function max(a,b:longint):longint;
30 begin
31 if a>b then exit(a);
32 exit(b);
33 end;
34
35 function min(a,b:longint):longint;
36 begin
37 if a<b then exit(a);
38 exit(b);
39 end;
40
41 procedure main;
42 begin
43 fillchar(f,sizeof(f),$ff);
44 fillchar(a,sizeof(a),0);
45 readln(n,m);
46 for i:=1 to n do readln(name[i]);
47 for i:=1 to m do
48 begin
49 readln(s);
50 t:=pos(' ',s);
51 s1:=copy(s,1,t-1);
52 s2:=copy(s,t+1,length(s)-length(s1)-1);
53 // writeln(s);
54 // writeln(s1);
55 // writeln(s2);
56 // writeln;
57 for j:=1 to n do
58 begin
59 if name[j]=s1 then t1:=j;
60 if name[j]=s2 then t2:=j;
61 end;
62 a[t1,t2]:=true;
63 a[t2,t1]:=true;
64 end;
65 //
66 // for i:=1 to n do writeln(name[i]);
67 //
68 f[1,1]:=1;
69 for i:=1 to n-1 do
70 for j:=i+1 to n do
71 begin
72 for k:=1 to j-1 do
73 begin
74 if (a[k,j])and(f[i,k]>0) then f[i,j]:=max(f[i,j],f[i,k]+1);
75 end;
76 f[j,i]:=f[i,j];
77 end;
78 maxn:=1;
79 for i:=1 to n-1 do if a[i,n] then maxn:=max(f[i,n],maxn);
80 writeln(maxn);
81 end;
82
83 begin
84 init;
85 main;
86 outit;
87 end.
88