參與考古挖掘的小明得到了乙份藏寶圖,藏寶圖上標出了 n 個深埋在地下的寶藏屋, 也給出了這 n 個寶藏屋之間可供開發的 m 條道路和它們的長度。
小明決心親自前往挖掘所有寶藏屋中的寶藏。但是,每個寶藏屋距離地面都很遠, 也就是說,從地面打通一條到某個寶藏屋的道路是很困難的,而開發寶藏屋之間的道路 則相對容易很多。
小明的決心感動了考古挖掘的贊助商,贊助商決定免費贊助他打通一條從地面到某 個寶藏屋的通道,通往哪個寶藏屋則由小明來決定。
在此基礎上,小明還需要考慮如何開鑿寶藏屋之間的道路。已經開鑿出的道路可以 任意通行不消耗代價。每開鑿出一條新道路,小明就會與考古隊一起挖掘出由該條道路 所能到達的寶藏屋的寶藏。另外,小明不想開發無用道路,即兩個已經被挖掘過的寶藏 屋之間的道路無需再開發。
新開發一條道路的代價是:l×
k\mathrm \times \mathrml×
kl代表這條道路的長度,k代表從贊助商幫你打通的寶藏屋到這條道路起點的寶藏屋所經過的 寶藏屋的數量(包括贊助商幫你打通的寶藏屋和這條道路起點的寶藏屋) 。
請你編寫程式為小明選定由贊助商打通的寶藏屋和之後開鑿的道路,使得工程總代 價最小,並輸出這個最小值。
輸入格式:
第一行兩個用空格分離的正整數 n 和 m,代表寶藏屋的個數和道路數。
接下來 m 行,每行三個用空格分離的正整數,分別是由一條道路連線的兩個寶藏 屋的編號(編號為 1~n),和這條道路的長度 v。
輸出格式:
輸出共一行,乙個正整數,表示最小的總代價。
輸入樣例#1:
複製
4 5輸出樣例#1:複製1 2 1
1 3 3
1 4 1
2 3 4
3 4 1
4輸入樣例#2:複製
4 5輸出樣例#2:複製1 2 1
1 3 3
1 4 1
2 3 4
3 4 2
【樣例解釋1】
小明選定讓贊助商打通了 1 號寶藏屋。小明開發了道路 1→
21 \to 21
→2,挖掘了
2 號寶 藏。開發了道路 1→
41 \to 41→
4,挖掘了
4 號寶藏。還開發了道路 4→
34 \to 34→
3,挖掘了
3 號寶 藏。工程總代價為:1×
1+1×
1+1×
2=41
\times 1 + 1 \times 1 + 1 \times 2 = 4 1×
1+1×
1+1×
2=4【樣例解釋2】
小明選定讓贊助商打通了 1 號寶藏屋。小明開發了道路 1→
21 \to 21
→2,挖掘了
2 號寶 藏。開發了道路 1→
31 \to 31→
3,挖掘了
3 號寶藏。還開發了道路 1→
41 \to 41→
4,挖掘了
4 號寶 藏。工程總代價為:1×
1+3×
1+1×
1=51
\times 1 + 3 \times 1 + 1 \times 1 = 51×
1+3×
1+1×
1=5【資料規模與約定】
對於 20%的資料: 保證輸入是一棵樹,1≤
n≤81
\le n \le 81≤
n≤8,
v≤50
00v \le 5000v≤
5000
且所有的 v 都相等。
對於 40%的資料: 1≤
n≤81
\le n \le 81≤
n≤8,
0≤m≤
1000
0 \le m \le 10000≤
m≤10
00,v
≤500
0v\le 5000v≤
5000
且所有的 v 都相等。
對於 70%的資料: 1≤
n≤81
\le n \le 81≤
n≤8,
0≤m≤
1000
0 \le m \le 10000≤
m≤10
00,v
≤500
0v\le 5000v≤
5000
對於 100%的資料: 1≤
n≤12
1 \le n \le 121≤
n≤12
,0≤m
≤100
00\le m \le 10000≤
m≤10
00,v
≤500
000v
\le 500000v≤
5000
00狀壓dp其實很明顯,n<=12 考場一眼狀壓
我們設f[s]表示已經打通了集合s中的點的最小代價,則對於集合中所有的點的邊,若能到達乙個不在集合中的點v,新狀態為e = s | (1 << v - 1),則f[e] = min(f[e],f[s] + w * g[s].d[u]);
其中g[s]儲存的是s狀態下各點的深度,由u點轉移,那麼代價就是【邊權】w * g[s].d[u]
但是要注意,乙個最優代價可能有多種深度方案,所以g[s]實際上應該是乙個表,儲存多個可能的深度【考場上就沒注意想】
總的複雜度是o(2 ^ n * n * m)
#include#include#include#include#include#define ll long long int#define rep(i,n) for (int i = 1; i <= (n); i++)
#define fo(i,x,y) for (int i = (x); i <= (y); i++)
#define redge(u) for (int k = head[u]; k != -1; k = edge[k].next)
using namespace std;
const int maxn = 15,maxm = 2005,maxv = 1 << 13,inf = 1000000000;
inline int read()
while (c >= 48 && c <= 57)
return out * flag;
}int head[maxn],nedge = 0;
struct edgeedge[maxm];
inline void build(int u,int v,int w);
head[u] = nedge++;
edge[nedge] = (edge) ;
head[v] = nedge++;
}int f[maxv],n,m,mv;
struct node
node(int u)
};vectorg[maxv];
void solve()
int to,e,t;
for (int s = 1; s <= mv; s++)else if (f[t] == f[s] + edge[k].w * g[s][l].d[i])}}
}}}}
printf("%d\n",f[mv]);
}void init()
}int main()
noip2017解題報告題解
noip 2017 提高組題解 by 杜瑜皓 november 12,2017 1 math 輸出 ab a b。因為如果 x,y 是 ax by n 的一組解,那麼 x bt,y at 也是一組解,容易發現最大的不滿足的 x,y 為 1,a 1 b 1,1 即 n ab a b 無解。2 comp...
NOIP2017 寶藏 題解(狀壓DP)
參與考古挖掘的小明得到了乙份藏寶圖,藏寶圖上標出了 nnn 個深埋在地下的寶藏屋,也給出了這 nnn 個寶藏屋之間可供開發的m mm 條道路和它們的長度。小明決心親自前往挖掘所有寶藏屋中的寶藏。但是,每個寶藏屋距離地面都很遠,也就是說,從地面打通一條到某個寶藏屋的道路是很困難的,而開發寶藏屋之間的道...
NOIP 2017 提高組 寶藏
傳送門 參與考古挖掘的小明得到了乙份藏寶圖,藏寶圖上標出了 n nn 個深埋在地下的寶藏屋,也給出了這 n nn 個寶藏屋之間可供開發的 m mm 條道路和它們的長度。小明決心親自前往挖掘所有寶藏屋中的寶藏。但是,每個寶藏屋距離地面都很遠,也就是說,從地面打通一條到某個寶藏屋的道路是很困難的,而開發...