国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學院 > 開發設計 > 正文

算法訓練 結點選擇 藍橋杯

2019-11-08 20:03:41
字體:
來源:轉載
供稿:網友
問題描述有一棵 n 個節點的樹,樹上每個節點都有一個正整數權值。如果一個點被選擇了,那么在樹上和它相鄰的點都不能被選擇。求選出的點的權值和最大是多少?輸入格式第一行包含一個整數 n 。接下來的一行包含 n 個正整數,第 i 個正整數代表點 i 的權值。接下來一共 n-1 行,每行描述樹上的一條邊。輸出格式輸出一個整數,代表選出的點的權值和的最大值。樣例輸入51 2 3 4 51 21 32 42 5樣例輸出12樣例說明選擇3、4、5號點,權值和為 3+4+5 = 12 。數據規模與約定對于20%的數據, n <= 20。對于50%的數據, n <= 1000。對于100%的數據, n <= 100000。

權值均為不超過1000的正整數。

樹形動態規劃

建立樹

其實就是儲存圖,有矩陣和鏈表。我這里用的是鏈式前向星,儲存的圖的思路是以每個點為起點,然后用head[i]儲存以i為起點的一條邊,通過鏈式結構遍歷所有邊。具體操作一個是邊結構,包含終點,和下一條邊的位置,另一個是添加函數,完成儲存終點,鏈式結構,指定新起始邊的任務。注意一條邊是屬于兩條邊的。

動態規劃

類似于最大獨立子集問題

子問題 以i為根節點的子樹權值和最大值

遞歸表達式    dp[x][0]+=max2(dp[k][0],dp[k][1]);(0不取x,1取x)                        dp[x][1]+=dp[k][0];

沒有重疊子問題,從葉開始只要算一遍。

#include<stdio.h>#define max2(a,b) a>b?a:b#define min2(a,b) a<b?a:b#define Max_ 100010int M=0;int dp[Max_][2];int head[Max_];struct edge{int to;int next;}e[Max_*2];void add(int v, int u){e[M].to=v;e[M].next=head[u];head[u]=M++;e[M].to=u;e[M].next=head[v];head[v]=M++;}void dfs(int x,int v){int i,k;for(i=head[x];i!=-1;i=e[i].next){    k=e[i].to;    if(k==v)continue;    dfs(k,x);    dp[x][0]+=max2(dp[k][0],dp[k][1]);    dp[x][1]+=dp[k][0];}}int main(){int n,i,u,v;scanf("%d",&n);memset(head,-1,sizeof(head));memset(dp,0,sizeof(dp));for(i=1;i<=n;i++){    scanf("%d",&dp[i][1]);}for(i=1;i<=n-1;i++){    scanf("%d%d",&u,&v);    add(u,v);}dfs(1,-1);PRintf("%d",max2(dp[1][1],dp[1][0]));return 0;}


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 吐鲁番市| 新巴尔虎左旗| 长宁县| 黔南| 玛曲县| 大洼县| 连江县| 新乐市| 鄢陵县| 恩平市| 图木舒克市| 麻城市| 广饶县| 伊金霍洛旗| 无为县| 舟山市| 论坛| 绥阳县| 嘉定区| 道孚县| 南靖县| 昭通市| 辽宁省| 花垣县| 楚雄市| 元氏县| 金平| 成安县| 马龙县| 贵德县| 永川市| 铜梁县| 杭锦旗| 博客| 元谋县| 江源县| 丰顺县| 舟曲县| 大兴区| 读书| 林周县|