POJ 3311 佛洛依德列舉

2021-07-16 23:36:47 字數 1602 閱讀 2167

題意:

有 n 個地點,之後告訴你n個地點的之間的距離,問從起點出發,經過所有的點後再回到起點,求最短路。

輸入:

3

0 1 10 10

1 0 1 2

10 1 0 10

10 2 10 0

0

輸出: 8

分析:tsp(旅行商)問題,可以先求出任意兩點之間的最短路g[i][j],直接三重迴圈的floyed就可以,之後將n個點全排列,列舉所有的狀態,找出全排列後的所

有點構成的迴路的最小

值即可。小技巧:全排列函式next_permutation(v.begin(),v.end())。

**:

做法:floyed+列舉:

#include#include#include#include#include#include#include#includeusing namespace std;

int n, g[11][11];

int main()

for(int k = 0; k <= n; k++) //floyed任意兩點最短路

}//之後列舉 n 個節點,所有節點的最小值即可。即:對n個節點全排列

vectorjeo;

for(int i = 1; i <= n; i++)

jeo.push_back(i);

int ans = -1;

dowhile(next_permutation(jeo.begin(), jeo.end()));

printf("%d\n", ans);

}return 0;

}

做法2:

floyed+dp狀態壓縮:

dp[i][j]是表示i狀態下最短路是j,其中i是用十一位二進位制表示10個城市,如果去過則標記為1,沒有則標記為0.

dp轉移方程:dp(s,i)=min(dp(s,i),dp(s^(1<

狀態,s=(1<

**:

#include#define inf 100000000

using namespace std;

int dis[12][12];

int dp[1<<11][12];

int n,ans,_min;

int main()

{ //freopen("in.txt","r",stdin);

while(scanf("%d",&n) && n)

{ for(int i = 0;i <= n;++i)

for(int j = 0;j <= n;++j)

scanf("%d",&dis[i][j]);

for(int k = 0;k <= n;++k)

for(int i = 0;i <= n;++i)

for(int j = 0;j <= n;++j)

if(dis[i][k] + dis[k][j] < dis[i][j])

dis[i][j] = dis[i][k] + dis[k][j];

for(int s = 0;s <= (1<

poj 3311 狀態壓縮dp

題目大意 類似於tsp問題,只是每個點可以走多次,比經典tsp問題不同的是要先用弗洛伊的預處理一下兩兩之間的距離。求最短距離。解析 可以用全排列做,求出乙個最短的距離即可。或者用狀態壓縮dp.用乙個二進位制數表示城市是否走過 狀態表示 dp state i 表示到達i點狀態為state的最短距離 狀...

POJ 3311 旅行商問題 狀態壓縮 dp

最近做 dp 做的起勁啊。旅行商問題的狀態壓縮 dp i j 表示 遍歷 i 中所有城市一遍 並且現在在 j 的最短距離是多少。第乙個點可以遍歷兩次所以先不設定為1,並且這個狀態是合法狀態,這個點曾經是最困擾我的。include include include include include inc...

3311 POJ 狀態壓縮

include include include include include include include include include include define ll int64 define lll unsigned long long define max 1000009 defin...