HDU 4568 Hunter 最短路 狀壓DP

2022-02-14 00:14:21 字數 1852 閱讀 8568

題意:給乙個n*m的格仔,格仔中有一些數,如果是正整數則為到此格仔的花費,如果為-1表示此格仔不可到,現在給k個寶藏的地點(k<=13),求乙個人從邊界外一點進入整個棋盤,然後拿走所有能拿走的寶藏的最小花費,如果一次不能拿走所有能拿到的或者根本拿不到任何寶藏,輸出0.

解法:看到k的範圍應該想到狀態壓縮,將每個格仔都看成乙個點,再新建兩個點,乙個表示邊界外的起點,用0表示,乙個表示邊界外的終點,用n*m+1表示,然後相互建邊,建有向邊,邊權為終點格仔的花費值,(其實都不用建邊,直接跑最短路也行)然後求這k+2個點兩兩之間的最短距離,然後就化成tsp問題了,用狀壓dp可以解決。

求k+2個點兩兩之間的最短距離可以跑k+2次spfa求出,複雜度不高。

**:

#include #include 

#include

#include

#include

#include

#include

#define mod 1000000007

using

namespace

std;

#define n 10007

int mp[304][304

];int c[304][304

];int dis[20][20

];int

n,m,k;

int d[50005

];struct

node

g[4*50005

];int head[4*50005

],tot;

int dx[4] = ;

int dy[4] = ;

int vis[50006

];struct

point

p[15

];int ok(int nx,int

ny)void addedge(int u,int v,int

w)void spfa(int

s) }

}}int dp[1

<<17][20

];int

main()

memset(head,-1,sizeof

(head));

tot = 0

;

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

if(i == 1 || i == n || j == 1 || j == m) //

邊界 }

}scanf("%d

",&k);

p[0].x = 1, p[0].y = 0

; p[k+1].x = n,p[k+1].y = m+1

;

for(i=1;i<=k;i++)

scanf(

"%d%d

",&p[i].x,&p[i].y),p[i].x++,p[i].y++;

for(i=0;i<=k+1;i++)

}for(i=0;i

<<16);i++)

for(j=0;j<16;j++)

dp[i][j]=mod;

for(i=0;i)

dp[1<1]=dis[0][i+1

];

for(i=0;i}}

int minn=mod;

for(i=1;i<=k;i++)

minn=min(dp[(1

<1][i]+dis[i][k+1

],minn);

if(minn ==mod)

cout

<<0

<

else

cout

}return0;

}

view code

hdu 4568 旅行商問題dp

這個題目題意描述不清,沒有說明只能進入一次。題目意思很好理解,不再重複。思路也比較好想,先計算每兩個寶藏區的最短路,和每個寶藏區到邊界的最短路,然後dp解決。在計算最短路的時候,用優先佇列優化的dijkstra演算法。在 1的處理上有些小技巧。但是!但是!我之前的思路是dp i 表示狀態i的最小co...

HDU 2544 最短路 最短路

最近複習了最短路徑的演算法,就寫了4個版本的測試。正好是模板題,就果斷a之。dijkstar版本 include include include include include include includeusing namespace std define n 110 define max 99...

hdu 2544 最短路(最短路)

time limit1000 ms memory limit32768 kb 在每年的校賽裡,所有進入決賽的同學都會獲得一件很漂亮的t shirt。但是每當我們的工作人員把上百件的衣服從商店運回到賽場的時候,卻是非常累的!所以現在他們想要尋找最短的從商店到賽場的路線,你可以幫助他們嗎?input輸入...