P4294 WC2008 遊覽計畫

2021-10-10 01:25:13 字數 3597 閱讀 1087

題目鏈結

題目描述

從未來過紹興的小d有幸參加了winter camp 2008,他被這座歷史名城的秀麗風景所吸引,強烈要求遊覽紹興及其周邊的所有景點。

主辦者將紹興劃分為 n

nn 行 m

mm 列 (n×

m)(n×m)

(n×m

) 個分塊,如下圖 (8×

景點含於方塊內,且乙個在這裡插入描述

方塊至多有乙個景點。無景點的方塊視為路。

為了保證安全與便利,主辦方依據路況和治安狀況,在非景點的一些方塊內安排不同數量的志願者;在景點內聘請導遊(導遊不是志願者)。在選擇旅遊方案時,保證任意兩個景點之間,存在一條路徑,在這條路徑所經過的每乙個方塊都有志願者或者該方塊為景點。既能滿足選手們遊覽的需要,又能夠讓志願者的總數最少。

例如,在上面的例子中,在每個沒有景點的方塊中填入乙個數字,表示控制該方塊最少需要的志願者數目:

圖中用深色標出的方塊區域就是一種可行的志願者安排方案,一共需要 20

2020

名志願者。由圖可見,兩個相鄰的景點是直接(有景點內的路)連通的(如沈園和八字橋)。

現在,希望你能夠幫助主辦方找到一種最好的安排方案。

輸入格式

第一行有兩個整數,n

nn 和 m

mm ,描述方塊的數目。

接下來 n

nn 行,每行有 m

mm 個非負整數,如果該整數為 0

00 ,則該方塊為乙個景點;

否則表示控制該方塊至少需要的志願者數目。相鄰的整數用(若干個)空格隔開,

行首行末也可能有多餘的空格。

輸出格式

由 n +1

n+1n+

1 行組成。第一行為乙個整數,表示你所給出的方案中安排的志願者總數目。

接下來 n

nn 行,每行 m

mm 個字元,描述方案中相應方塊的情況:

『_』(下劃線)表示該方塊沒有安排志願者;

『o』(小寫英文本母o)表示該方塊安排了志願者;

『x』(小寫英文本母x)表示該方塊是乙個景點;

注:請注意輸出格式要求,如果缺少某一行或者某一行的字元數目和要求不一致(任何一行中,多餘的空格都不允許出現),都可能導致該測試點不得分。

輸入輸出樣例

輸入 #1

440

1102

5511

5510110

輸出 #1

6

xoox

___o

___o

xoox

說明/提示

1 ≤n

,m,k

≤101\le n,m,k\le10

1≤n,m,

k≤10

斯坦納樹

問題描述:求乙個無向圖中包含 k

kk 個關鍵點的最小生成樹。

演算法實現:採用狀壓dp來求解。設 dp[

i][s

]dp[i][s]

dp[i][

s]為以節點 i

ii 為根,包含關鍵節點的子集 s

ss 的最小權值之和。

因此狀態轉移方程為:

d p[

i][s

]=\min\limits_ (dp[i][s],dp[i][t]+dp[i][s-t]) \\ \min\limits_(dp[i][s],dp[j][s]+w_) \end\right.

dp[i][

s]=⎩

⎨⎧​t

⊆smin​(d

p[i]

[s],

dp[i

][t]

+dp[

i][s

−t])

1≤j≤

n,j

​=imin​(

dp[i

][s]

,dp[

j][s

]+wi

,j​)

​第乙個轉移方程通過列舉 s

ss 的子集求解;第二個轉移方程通過最短路演算法求解。

若採用dijkstra演算法轉移第二個方程,則時間複雜度為 o(3

kn+2

kmlog⁡m)

o(3^kn+2^km\log m)

o(3kn+

2kmlogm)

#include

#define pii pair

#define fi first

#define se second

#define inf 0x3f3f3f3f

using

namespace std;

const

int n =11;

struct node };

const

int dx[4]

=;const

int dy[4]

=;int n, m, k;

int dp[n]

[n][

1<<10]

, a[11]

[n];

pair

int> pre[n]

[n][

1<<10]

;bool v[n]

[n], ans[n]

[n];

pii key;

priority_queue q;

inline

void

dijkstra

(int s)

, s}

; q.

push()

;}}}

}void

dfs(pii u,

int s)

intmain()

, dp[i]

[j][

1<<

(k++)]

=0;}

for(

int s =

1; s

<< k)

; s++

), t};}

if(dp[i]

[j][s]

!= inf)q.

push()

;}dijkstra

(s);

}printf

("%d\n"

, dp[key.fi]

[key.se][(

1<< k)-1

]);dfs

(key,(1

<< k)-1

);for(

int i =

1; i <= n; i++

)return0;

}

洛谷P4294 WC2008 遊覽計畫

教練上次課講了插頭dp,然後列出的插頭dp題目裡有這道題。本來想練練插頭dp的結果用更快更簡單的斯坦納樹解決了這道題。斯坦納樹經典題目。斯坦納樹其實並不是很難,一般用來解決在一張無向圖上選 text 個點使這 text 個點連通並且始所選邊邊權最小。那麼回到本題。設 f 表示當前在第 text 行 ...

P4294 WC2008 遊覽計畫 斯坦納樹

題目鏈結 差不多是斯坦納樹裸題,不過邊權化成了點權,這樣在合併兩棵子樹時需要去掉根結點的權值,防止重複。題目還要求輸出解,只要在轉移時記錄下路徑,然後dfs一遍就好了。1 include2 using namespace std 3 typedef long long ll 4 const int ...

2595 Wc2008 遊覽計畫

time limit 10 sec memory limit 256 mbsec special judge submit 1312 solved 602 submit status discuss 第一行有兩個整數,n和 m,描述方塊的數目。接下來 n行,每行有 m 個非負整數,如果該整數為 0,...