HDU_2196 Computer (樹型dp)

來源:互聯網
上載者:User

  糾結的問題。做了兩天,還是在拜讀大牛代碼的情況下ac的。好好謝謝總結吧。

  諸位大牛的思路是兩次dfs。前提:建樹的時候按無向邊從上往下建。第一次dfs是搜出一個根結點到其他結點的最長路徑和次長路徑(次長路徑不是最長路徑的子路徑,也就是說不在同一條路上。)

  一個結點到其他結點的最長路徑怎麼得到?1、可能是從這個結點往下取到最長路徑。2、可能是從這個結點的父結點上選去另一條路徑。

  當情況一時:第一次dfs所得的最長路徑就是要求的結果。當情況二時:第一次dfs所得的次長路徑就是所求結果。

  另外,因為是無向邊建樹,所以第一次dfs從下往上搜,第二次dfs從上往下搜。

  具體實現:定義dp[i]表示i到其他結點的最長路徑。 f[i]表示從i結點到他的子結點的最長路徑 l[i]表示i到其子結點的次長路徑。 dir[i]表示最長路徑所在的方向,防止最長路徑跟次長路徑重複。

核心代碼:

void dfs_0(int r) {
if(f[r]) return ;
int len = g[r].size();
if(len == 0) return ;
int i, max = -1, flag = -1, flag1 = -1, c;
for(i = 0; i < len; i++) {
c = g[r][i].c;
dfs_0(c);
if(f[c] + g[r][i].val > max) {
max = f[c] + g[r][i].val;
flag = i;
}
}
f[r] = max;
dir[r] = flag;
max = -1;
for(i = 0; i < len; i++) {
c = g[r][i].c;
if(f[c] + g[r][i].val > max && i != flag) {
max = f[c] + g[r][i].val;
flag1 = i;
}
}
if(flag1 != -1) l[r] = max;
}

void dfs_1(int r) {
int i, len, c;
len = g[r].size();
for(i = 0; i < len; i++) {
c = g[r][i].c;
if(i == dir[r])
dp[c] = max(dp[r], l[r]) + g[r][i].val;
else
dp[c] = max(dp[r], f[r]) + g[r][i].val;
dfs_1(c);
}
}

ps:因為可能出現整顆樹只有一條邊的情況,所以輸出結果時取f[i] 和dp[i]的最大。

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.