题目大意
给你n个城市(1~n)和一个PIZZA店(0),要求找一条回路,从0出发,又回到0,而且距离最短。
分析
先用floyd把任意I,j两点的最短路找出来。
再DP:
D[I,j]=min(d[I,j],d[i xor (1 shl (j-1)),k]+f[k,j])((i and (1 shl (j-1)))<>0)(1<=j,k<=n)
其中i表示用二进制表示n个城市,1表示经过,0表示没有经过。F表示k到j的最短路。
结果即为min(d[1 shl n-1][j]+f[j][0]){因为还要回点0}
代码
var
f:array[0..100,0..100] of longint;
d:array[0..5000,0..100] of longint;
c:array[0..100] of longint;
i,j,k,l:longint;
n:longint;
ans:longint;
begin
readln(n);
while n<>0 do
begin
for i:=0 to n do
begin
for j:=0 to n do
read(f[i,j]);
readln;
end;
for k:=0 to n do
for i:=0 to n do
for j:=0 to n do
if (i<>j) and (i<>k) and (j<>k)
then
if f[i,k]+f[k,j]<f[i,j]
then
f[i,j]:=f[i,k]+f[k,j];
fillchar(d,sizeof(d),$7f);
d[0][1]:=0;
for i:=0 to 1 shl n-1 do
begin
for j:=1 to n do
begin
if i=1 shl (j-1)
then d[i][j]:=f[0][j];
if (i and (1 shl (j-1)))<>0
then
begin
l:=i xor (1 shl (j-1));
for k:=1 to n do
if (l and (1 shl (k-1)))<>0
then if d[l][k]+f[k,j]<d[i][j]
then d[i][j]:=d[l][k]+f[k,j];
end;
end;
end;
ans:=maxlongint;
for i:=1 to n do
if ans>d[1 shl n-1][i]+f[i][0] then ans:=d[1 shl n-1][i]+f[i][0];
writeln(ans);
readln(n);
end;
end.