水題挑戰3 NOIP 2017 寶藏

2022-08-15 08:06:08 字數 2625 閱讀 8136

參與考古挖掘的小明得到了乙份藏寶圖,藏寶圖上標出了 \(n\) 個深埋在地下的寶藏屋, 也給出了這 \(n\) 個寶藏屋之間可供開發的 \(m\) 條道路和它們的長度。

小明決心親自前往挖掘所有寶藏屋中的寶藏。但是,每個寶藏屋距離地面都很遠, 也就是說,從地面打通一條到某個寶藏屋的道路是很困難的,而開發寶藏屋之間的道路 則相對容易很多。

小明的決心感動了考古挖掘的贊助商,贊助商決定免費贊助他打通一條從地面到某 個寶藏屋的通道,通往哪個寶藏屋則由小明來決定。

在此基礎上,小明還需要考慮如何開鑿寶藏屋之間的道路。已經開鑿出的道路可以 任意通行不消耗代價。每開鑿出一條新道路,小明就會與考古隊一起挖掘出由該條道路 所能到達的寶藏屋的寶藏。另外,小明不想開發無用道路,即兩個已經被挖掘過的寶藏 屋之間的道路無需再開發。

新開發一條道路的代價是:

\(\mathrm \times \mathrm\)

\(l\)代表這條道路的長度,\(k\)代表從贊助商幫你打通的寶藏屋到這條道路起點的寶藏屋所經過的 寶藏屋的數量(包括贊助商幫你打通的寶藏屋和這條道路起點的寶藏屋) 。

請你編寫程式為小明選定由贊助商打通的寶藏屋和之後開鑿的道路,使得工程總代 價最小,並輸出這個最小值。

輸入格式

第一行兩個用空格分離的正整數 \(n,m\),代表寶藏屋的個數和道路數。

接下來 \(m\) 行,每行三個用空格分離的正整數,分別是由一條道路連線的兩個寶藏 屋的編號(編號為 \(1-n\)),和這條道路的長度 \(v\)。

輸出格式

乙個正整數,表示最小的總代價。

【資料規模與約定】

對於 \(\%20\)的資料: 保證輸入是一棵樹,\(1 \le n \le 8\),\(v \le 5000\) 且所有的 \(v\) 都相等。

對於 \(\%40\)的資料: \(1 \le n \le 8\),\(0 \le m \le 1000\),\(v \le 5000\) 且所有的 \(v\)都相等。

對於 \(\%70\)的資料: \(1 \le n \le 8\),\(0 \le m \le 1000\),\(v \le 5000\)

對於 \(\%100%\)的資料: \(1 \le n \le 12\),\(0 \le m \le 1000\),\(v \le 500000\)

好吧其實這題還是有點難的,蒟蒻我當時還是在考場上拿到這題一臉懵逼。

看到這題的規模,\(n \le 12\),一般就會有幾種想法:爆搜,狀壓(還有大佬寫的模擬退火。。。是本弱弱不會的了) 。

由題意可得,我們求完之後會是一棵樹,圖上找一棵樹。

首先,我們想到某乙個點\(i\) 作為這個圖中樹的根,對於其他點,我們關心其他點到起點的距離。

對於第一部分分,我們只需要對每乙個根做一次樹形dp即可。

之後變成了乙個圖,我們考慮狀態壓縮。

我們記 \(f[s][i]\) , 表示我們對於狀態為 \(s\) 的點集,最深層數為 \(i\) 。

然後我們可以稍微思考一下,對於點集 \(s\) ,他可以由自己的子點集 \(s1\) 轉移而來, ,於是,我們就有:

\(f[s][d] = min, s1\subset s\)

解釋一下,這個式子相當於就是把\(s1\) 中的點,向外擴充套件一層,擴充套件完點集為\(s\)。

\(transfer[s1][s]\) 表示從 \(s1\)到 \(s\) 的最小價值。

我們考慮s中點\(i\), 不在\(s1\) 中, 那麼從\(i\) 轉移到\(s1\) 的最小價值為:

\(w[i][s1] = min(e[i][j]), j \in s1\)

但是事實上這個w陣列是不用寫出來的,一次次加上去就好了。

然後\(transfer[s1][s] = \sigma w[i][s1] ,i\in s, i\notin s1\)

但是吧,不知道大家有沒有這個困惑

在我寫完時候也有點糾結(糾結了好久,寫完才想到)

其實我們考慮乙個點

我不會畫畫(偷懶),引用了大佬的部落格goldenpotato的oi世界

考慮這個圖里,我們以圖中給的為根,如果我們統計k=1時候沒有加最右邊的乙個點,到k=2的狀態時把這個點算進去,那不是距離根節點只有乙個寶藏屋的邊要\(\times 2\)

顯然是不對的。

但是我們可以在其他點為根的狀態中,把這個點加進去,就一定會有最優的解。

所以我們的答案統計為: \(ans = min

typedef long long ll;

const int n=14;

int n, m, inf, tr[1<

int main()

rep(s, 0, (1<

}if( tt == inf )

tr[s1][s] += tt;}}

if( flag )

} }

memset(f, 63, sizeof(f));

ll ans=f[0][0];

rep(i, 1, n) f[1][1<

rep(i, 2, n)

} rep(i, 1, n) ans=min(ans, f[i][(1<

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

return 0;

}

NOIP水題(思路)

problem describition 接水問題 學校裡有乙個水房,水房裡一共裝有m 個龍頭可供同學們開啟水,每個龍頭每秒鐘的供水量相等,均為1。現在有n 名同學準備接水,他們的初始接水順序已經確定。將這些同學按接水順序從1到n 編號,i 號同學的接水量為wi。接水開始時,1 到m 號同學各佔乙個...

noip模擬賽 水題

題目描述 lyk出了道水題。這個水題是這樣的 有兩副牌,每副牌都有n張。對於第一副牌的每張牌長和寬分別是xi和yi。對於第二副牌的每張牌長和寬分別是aj和bj。第一副牌的第i張牌能覆蓋第二副牌的第j張牌當且僅當xi aj並且yi bj。注意牌不能翻轉 當然一張牌只能去覆蓋最多一張牌,而不能覆蓋好多張...

NOIP模擬 水管(水題)

為什麼打了endl竟然沒t。但為什麼交到 上又t了 氵題嘛,做法有很多種啊。我選擇加n 1條邊,這樣就保證了聯通,直接dfs一遍記錄兒子,邊權就是兒子的值,注意修改反向邊。然後一群人拿著我的程式去比誰跑得快 includeusing namespace std const int maxn 2e5 ...