算法:DP
分析:貌似不是一道很难的DP,但是也没做出来。
我们可以把一个人走一条回路当成两个人在走路,当其中一人走到i城市时另一人走到j城市,用f[i,j]表示这一状态最多能经过多少个城市。
设第二个人总比第一个人走的快,也就是他总在第一个人前面,考虑这样一种情况,f[i,k]>0 且 b[k,j] 那么f[i,j]=max{f[i,j],f[i,k]+1}。
最后我们打擂台找出最大的f[i,n]即可(b[i,n]=true)(因为到达最西边才能返回)。初始化f[1,1]=1,即起点到起点最多经过1个城市。
把其余的f值全设成-无穷即可。
分析:貌似不是一道很难的DP,但是也没做出来。
我们可以把一个人走一条回路当成两个人在走路,当其中一人走到i城市时另一人走到j城市,用f[i,j]表示这一状态最多能经过多少个城市。
设第二个人总比第一个人走的快,也就是他总在第一个人前面,考虑这样一种情况,f[i,k]>0 且 b[k,j] 那么f[i,j]=max{f[i,j],f[i,k]+1}。
最后我们打擂台找出最大的f[i,n]即可(b[i,n]=true)(因为到达最西边才能返回)。初始化f[1,1]=1,即起点到起点最多经过1个城市。
把其余的f值全设成-无穷即可。
注意此题为双向边。
{
ID:1011mashuo
PROG:tour
LANG:PASCAL
}
program tour;
const
maxn=100;
var
n,m,ans:longint;
name:array [0..maxn] of string;
f:array [0..maxn,0..maxn] of longint;
b:array [0..maxn,0..maxn] of boolean;
function find(x:ansistring):longint;
var
i:longint;
begin
for i:=1 to n do if name[i]=x then exit(i);
end;
procedure init;
var
i,t,x1,x2:longint;
s,s1,s2:string;
begin
readln(n,m);
for i:=1 to n do readln(name[i]);
for i:=1 to m do
begin
readln(s);
t:=pos(' ',s);
s1:=copy(s,1,t-1);
s2:=copy(s,t+1,length(s)-t);
x1:=find(s1);
x2:=find(s2);
b[x1,x2]:=true;
b[x2,x1]:=true;
end;
end;
function max(x,y:longint):longint;
begin
if x>y then exit(x) else exit(y);
end;
procedure main;
var
i,j,k:longint;
begin
fillchar(f,sizeof(f),255);
f[1,1]:=1;
for i:=1 to n-1 do
begin
for j:=i+1 to n do
begin
for k:=1 to j-1 do
begin
if (b[j,k]) and (f[i,k]>0) then f[i,j]:=max(f[i,j],f[i,k]+1);
f[j,i]:=f[i,j];
end;
end;
end;
end;
procedure outit;
var
i:longint;
begin
ans:=1;
for i:=1 to n do if b[i,n] then ans:=max(ans,f[i,n]);
end;
begin
assign(input,'tour.in'); reset(input);
assign(output,'tour.out'); rewrite(output);
init;
main;
outit;
writeln(ans);
close(input); close(output);
end.