【codevs2800】送外賣
阿新 • • 發佈:2018-12-16
題目描述 Description
有一個送外賣的,他手上有n份訂單,他要把n份東西,分別送達n個不同的客戶的手上。n個不同的客戶分別在1~n個編號的城市中。送外賣的從0號城市出發,然後n個城市都要走一次(一個城市可以走多次),最後還要回到0點(他的單位),請問最短時間是多少。現在已知任意兩個城市的直接通路的時間。
輸入描述 Input Description
第一行一個正整數n (1<=n<=15)
接下來是一個(n+1)*(n+1)的矩陣,矩陣中的數均為不超過10000的正整數。矩陣的i行j列表示第i-1號城市和j-1號城市之間直接通路的時間。當然城市a到城市b的直接通路時間和城市b到城市a的直接通路時間不一定相同,也就是說道路都是單向的。
輸出描述 Output Description
一個正整數表示最少花費的時間
樣例輸入 Sample Input
3 0 1 10 10 1 0 1 2 10 1 0 10 10 2 10 0
1
2
3
4
5
3
0 1 10 10
1 0 1 2
10 1 0 10
10 2 10 0
樣例輸出 Sample Output
8
資料範圍及提示 Data Size & Hint
1<=n<=15
解析:
Floyd+狀壓DP。
程式碼;
#include <bits/stdc++.h> using namespace std; int n,m,ans=1e9; int f[17][1<<16],d[17][17],ed; int main() { scanf("%d",&n);ed=(1<<(n+1))-1; for(int i=0;i<=n;i++) for(int j=0;j<=n;j++) scanf("%d",&d[i][j]); for(int k=0;k<=n;k++) for(int i=0;i<=n;i++) for(int j=0;j<=n;j++) d[i][j]=min(d[i][k]+d[k][j],d[i][j]); memset(f,0x3f,sizeof(f));f[0][0]=0; for(int i=0;i<=ed;i++) for(int now=0;now<=n;now++) for(int from=0;from<=n;from++) { if(((i|(1<<now))!=i))continue; f[now][i]=min(f[now][i],f[from][i^(1<<now)]+d[from][now]); } cout<<f[0][ed]; return 0; }