日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

精简改良(生成树dp)

發布時間:2024/4/15 编程问答 22 豆豆
生活随笔 收集整理的這篇文章主要介紹了 精简改良(生成树dp) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
精簡改良

尚未提交?尚未通過?時間限制:2000ms?內存限制:256MB

0.00%

提交人數:1

通過人數:0

題目描述

?

可憐最近在玩一款硬核戰爭游戲。

可憐控制的國家有?nn?座城市,在?nn?座城市之間有?mm?條雙向道路,第?ii?條道路連接了城市?u_iui??和?v_ivi?,且通過這條道路的時間為?w_iwi?

最近,可憐點了名為"傳送"的科技,這個科技可以讓可憐的士兵能在國家的任意兩個城市之間不經過道路快速地傳送。這樣從戰爭的角度來說,道路幾乎就沒有用了,可憐希望能刪除一些道路,使得道路系統盡可能地不便,這樣在敵人入侵時就能獲得優勢。

游戲的規則規定在任何時刻,同一個國家的任意兩個城市之間都必須要能通過道路到達。因此可憐需要保證在刪除道路之后,道路系統仍然是聯通的。

令?d(i,j)d(i,j)?為通過道路系統從第?ii?個城市到第?jj?個系統的最短時間,可憐定義一個道路系統的復雜度為?\sum_{i=1}^n \sum_{j=i+1}^n d(i,j)i=1n?j=i+1n?d(i,j)。可憐希望能刪除一些道路,在保證圖聯通的情況下,使道路系統的復雜度盡可能的大。

?

? ?

輸入描述

?

一行輸入兩個整數?n,m(1 \leq n \leq 14, 1 \leq m \leq \frac{n(n-1)}{2})n,m(1n14,1m2n(n?1)?),表示城市數量與初始的道路數量。

接下來?mm?行每行輸入三個整數?u_i,v_i,w_i(1 \leq u_i,v_i \leq n, 1 \leq w_i \leq 10^9)ui?,vi?,wi?(1ui?,vi?n,1wi?109),描述了一條道路。

輸入保證圖中沒有自環、重邊,同時圖是聯通的。

?

輸出描述

?

輸出一行一個整數,表示道路系統最大的可能的復雜度。

?

樣例輸入 1?

5 5 1 2 1 1 3 1 2 4 1 2 5 1 1 5 1

樣例輸出 1

20

樣例輸入 2?

5 10 1 2 1 1 3 2 1 4 3 1 5 4 2 3 5 2 4 6 2 5 7 3 4 8 3 5 9 4 5 10

樣例輸出 2

146



生成樹dp 套路
dp[s][i] 集合 s,以i為樹根的 什么什么東西
兩個集合合并的時候考慮連接兩個集的邊
然后用到了子集的遍歷




1 #include <bits/stdc++.h> 2 using namespace std; 3 4 #define ll long long 5 #define INFLL 0x3f3f3f3f3f3f3f3f 6 #define N 110 7 int n, m; 8 int dist[20][20]; 9 ll f[1 << 15][15]; 10 11 vector <int> vec[1 << 15]; 12 int sze[1 << 15]; 13 14 int main() 15 { 16 while (scanf("%d%d", &n, &m) != EOF) 17 { 18 memset(dist, -1, sizeof dist); 19 memset(f, -1, sizeof f); 20 for (int S = 0, len = (1 << n); S < len; ++S) 21 { 22 for (int i = 0; i < n; ++i) if ((S >> i) & 1) 23 vec[S].push_back(i + 1); 24 sze[S] = vec[S].size(); 25 if (sze[S] == 1) 26 f[S][*vec[S].begin()] = 0; 27 } 28 for (int i = 1, u, v, w; i <= m; ++i) 29 { 30 scanf("%d%d%d", &u, &v, &w); 31 dist[u][v] = dist[v][u] = w; 32 } 33 ll res = 0; 34 for (int S = 1, len = (1 << n); S < len; ++S) 35 { 36 for (auto u : vec[S]) 37 { 38 for (int T = (S - 1) & S; T != 0; T = (T - 1) & S) // 枚舉子集 39 { 40 for (auto v : vec[T]) 41 { 42 if (dist[u][v] == -1 || f[T][v] == -1 || f[S - T][u] == -1) continue; 43 f[S][u] = max(f[S][u], f[T][v] + f[S - T][u] + 1ll * dist[u][v] * sze[T] * (n - sze[T])); 44 } 45 } 46 if (S == (1 << n) - 1)res = max(res, f[S][u]); 47 } 48 } 49 printf("%lld\n", res); 50 } 51 return 0; 52 }

?








?

轉載于:https://www.cnblogs.com/zhangbuang/p/10956909.html

總結

以上是生活随笔為你收集整理的精简改良(生成树dp)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。