多校JLU 10題JLUCPC(樹形DP)

來源:互聯網
上載者:User

 

題目測試的時候感覺題就很噁心,10道都不會,不過在正式比賽的時候還是有隊伍犀利的做出了6道,真的很厲害

這個是最水的一題了,但是對我還是很難,看著題解,劃拉半天才看明白。

代碼最佳化後JOJ跑了0.57s。(上午剛看明白,下午比賽就出了)

師兄給的題解:

樹狀DP

因為樹是連通的且為無向邊,所以可以假定1為根,從結點1開始向各個子樹DFS
這次DFS過程中要對每個結點記錄幾個量
node[i]記錄以i為根的子樹(包括i結點)的T[k] 和
sum[i]記錄以i為根的子樹(包括i結點)中,每個結點到根的路徑長度*T[k]的和

所以第1遍DFS得到的sum[1]是以1為the most convenient location的答案,那麼開始枚舉以不同結點為the most convenient location的情況
對於

    1
   / \
  2   3
 /
4

比如轉移到2節點,則以2節點為the most convenient location 的答案是

Sum[1] –  sum_node[2] * g[1][2] + ( sum_node[1] –  sum_node[2]) * g[1][2] = Sum[2]

(g[1][2]表示1到2這條邊的權值)

接著對於以4節點為the most convenient location 的答案是

 Sum[2] –  sum_node[4] * g[2][4] + ( sum_node[1] –  sum_node[4]) * g[2][4] = Sum[4]

以此類推,這樣子DFS一遍即可

 

#include <cstdio>#include <string.h>const int maxn=100005;struct Edge{    int v,next,w;}edge[2*maxn];int cnt,n,head[maxn];long long node[maxn],sum[maxn],sum_node[maxn];bool vis[maxn];void addedge(int u,int v,int w){    edge[cnt].v=v;    edge[cnt].w=w;    edge[cnt].next=head[u];    head[u]=cnt++;    edge[cnt].v=u;    edge[cnt].w=w;    edge[cnt].next=head[v];    head[v]=cnt++;}void dfs (int u){    int v,i,t=head[u],w;    vis[u]=true ;    sum_node[u]=node[u];    for (;~t;t=edge[t].next)    {        v=edge[t].v;        if(vis[v])continue;        w=edge[t].w;        dfs(v);        sum_node[u]+=sum_node[v];        sum[0]+=w*sum_node[v];    }}void dfs2 (int u){    int v,t,w;    vis[u]=true ;    for (t=head[u]; ~t ; t=edge[t].next)    {        v=edge[t].v;        if(vis[v])continue;        w=edge[t].w;        sum[v]=sum[u]+(sum_node[0]-(sum_node[v]<<1))*w;        dfs2(v);    }}inline void init (){    memset (head , -1 ,sizeof(head));    memset (vis , 0 , sizeof(vis));    sum[0]=0;    cnt=0;}long long sovle (){    int  i;    dfs(0);    memset (vis , false , sizeof(vis));    dfs2(0);    long long min_num=sum[0];    for (i=0 ; i<n ; ++i)    if(min_num>sum[i]) min_num=sum[i];    return min_num;}int main (){    int i,u,v,w;    while (~scanf("%d",&n))    {        init ();        for (i=0 ; i<n ; ++i)         scanf("%d",node+i);        for (i=1 ; i<n ; ++i)        {            scanf("%d%d%d",&u,&v,&w);            u--;v--;            addedge (u,v,w);        }        printf("%lld\n",sovle());    }    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.