[CodeVS2800] 送外卖

来源:互联网 发布:计算机统考模拟软件 编辑:程序博客网 时间:2024/06/11 23:38

传送门

http://codevs.cn/problem/2800/

题目大意

给定n个点间的距离的邻接矩阵,询问从0出发走过所有点再回到0的最短距离,1个点可以多次访问

题解

状压DP
dp[i,j]:i表示状态,j表示该状态下最后访问的点

var w:array[0..20,0..20]of longint; dp:array[0..42000,0..20]of longint; i,j,k:longint; n,ans:longint;function min(a,b:longint):longint;begin if a>b then exit(b) else exit(a);end;begin readln(n); for i:=0 to n do  for j:=0 to n do   read(w[i,j]); for k:=0 to n do  for i:=0 to n do   for j:=0 to n do    w[i,j]:=min(w[i,k]+w[k,j],w[i,j]); for i:=1 to 1<<n-1 do  for j:=0 to n do   dp[i,j]:=1000000000; dp[0,0]:=0; for i:=1 to (1<<n)-1 do  for j:=0 to n do   begin    if (j<>0)and(i and (1<<(j-1))=0) then continue;    for k:=0 to n do     begin      if (j=k)or((k<>0)and(i and (1<<(k-1))=0)) then continue;      dp[i,j]:=min(dp[i,j],dp[i,k]+w[k,j]);      if j<>0 then dp[i,j]:=min(dp[i,j],dp[i-(1<<(j-1)),k]+w[k,j]);     end;   end; ans:=maxlongint; for i:=1 to n do  if ans>dp[1<<n-1,i]+w[i,0] then ans:=dp[1<<n-1,i]+w[i,0]; writeln(ans);end.
0 0
原创粉丝点击