參與考古挖掘的小明得到了乙份藏寶圖,藏寶圖上標出了 \(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 ...