HDU 2196 Computer(樹形dp經典)

來源:互聯網
上載者:User

本文出自   http://blog.csdn.net/shuangde800

題目傳送門

題意:

給出一棵樹,求離每個節點最遠的點的距離

思路:

把無根樹轉化成有根樹分析,

對於上面那棵樹,要求距結點2的最長距離,那麼,就需要知道以2為頂點的子樹(藍色圈起的部分,我們叫它Tree(2)),距頂點2的最遠距離L1

還有知道2的父節點1為根節點的樹Tree(1)-Tree(2)部分(即紅色圈起部分),距離結點1的最長距離+dist(1,2) = L2,那麼最終距離結點2最遠的距離就是max{L1,L2}

f[i][0],表示頂點為i的子樹的,距頂點i的最長距離
f[i][1],表示Tree(i的父節點)-Tree(i)的最長距離+i跟i的父節點距離

要求所有的f[i][0]很簡單,只要先做一次dfs求每個結點到葉子結點的最長距離即可。
然後要求f[i][1], 可以從父節點遞推到子節點,

假設節點u有n個子節點,分別是v1,v2...vn
那麼
如果vi不是u最長距離經過的節點,f[vi][1] = dist(vi,u)+max(f[u][0], f[u][1])
如果vi是u最長距離經過的節點,那麼不能選擇f[u][0],因為這儲存的就是最長距離,要選擇Tree(u)第二大距離secondDist,
可得f[vi][1] = dist(vi, u) + max(secondDist, f[u][1])

代碼:

/**========================================== *   This is a solution for ACM/ICPC problem * *   @author: shuangde *   @blog: blog.csdn.net/shuangde800 *   @email: zengshuangde@gmail.com *===========================================*/#include<iostream>#include<cstdio>#include<algorithm>#include<vector>#include<queue>#include<cmath>#include<cstring>using namespace std;typedef long long int64;const int INF = 0x3f3f3f3f;const double PI  = acos(-1.0);const int MAXN = 10010;struct Node{    int v, w;};vector<Node>adj[MAXN];int indeg[MAXN];int val[MAXN];int n, m;int64 f[MAXN][2];int vis[MAXN];int64 dfs1(int u){    vis[u] = true;    f[u][0] = 0;    for(int i=0; i<adj[u].size(); ++i){        int v = adj[u][i].v;        int w = adj[u][i].w;        if(vis[v]) continue;        f[u][0] = max(f[u][0], dfs1(v)+w);    }    return f[u][0];}void dfs2(int u, int fa_w){    vis[u] = true;    int max1=0, v1, max2=0, v2;    for(int i=0; i<adj[u].size(); ++i){        int v = adj[u][i].v;        int w = adj[u][i].w;        if(vis[v]) continue;        int tmp = f[v][0] + w;        if(tmp > max1){            max2 = max1; v2 = v1;            max1 = tmp; v1 = v;        }else if(tmp == max1 || tmp>max2){            max2 = tmp;            v2 = v;        }    }    if(u != 1){         int tmp = f[u][1];        int v = -1;        if(tmp > max1){            max2 = max1; v2 = v1;            max1 = tmp; v1 = v;        }else if(tmp == max1 || tmp>max2){            max2 = tmp;            v2 = v;        }    }    for(int i=0; i<adj[u].size(); ++i){        int v = adj[u][i].v;        int w = adj[u][i].w;        if(vis[v]) continue;        if(v==v1){            f[v][1] = max2 + w;        }else{            f[v][1] = max1 + w;         }        dfs2(v, w);    }}int main(){    while(~scanf("%d", &n) && n){        for(int i=1; i<=n; ++i) adj[i].clear();        for(int u=2; u<=n; ++u){            int v, w;            scanf("%d%d", &v, &w);            adj[u].push_back((Node){v, w});            adj[v].push_back((Node){u, w});        }                memset(f, 0, sizeof(f));        memset(vis, 0, sizeof(vis));        dfs1(1);        memset(vis, 0, sizeof(vis));        dfs2(1, 0);        for(int i=1; i<=n; ++i){            cout << max(f[i][0], f[i][1]) << endl;        }    }    return 0;}

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.