zoukankan      html  css  js  c++  java
  • noi 2003 逃学的小孩 树型DP

    思路:本题就是求在树上 MAX(dis[A,B]+MIN(dis[A,C]+dis[B,C]))

    可以证明AB是树上最长链

      1 #include<iostream>
      2 #include<cstdio>
      3 #include<cmath>
      4 #include<cstring>
      5 using namespace std;
      6 #define MAXN 200001
      7 struct node
      8 {
      9     int num;
     10     long long weight;
     11     node *next;
     12 };
     13 node *graph[MAXN],memo[2*MAXN];
     14 int father[MAXN],dp[MAXN],Q[MAXN],path[MAXN];
     15 long long d1[MAXN],d2[MAXN];
     16 int n,m,top=0;
     17 long long longest_chain=0;
     18 pair<int,int> longest_node;
     19 void add(int x,int y,long long z)
     20 {
     21     node *p=&memo[top++];
     22     p->num=y; p->next=graph[x]; p->weight=z; graph[x]=p;
     23     p=&memo[top++];
     24     p->num=x; p->next=graph[y]; p->weight=z; graph[y]=p;
     25 }
     26 void bfs(int s,long long d[])
     27 {
     28     memset(father,0,sizeof(father));
     29     memset(Q,0,sizeof(Q));
     30     int left,right;
     31     Q[left=right=1]=s;
     32     while(left<=right)
     33     {
     34         int u=Q[left++];
     35         for(node *p=graph[u];p;p=p->next)
     36         if(p->num!=father[u])
     37         {
     38             father[p->num]=u;
     39             d[p->num]=d[u]+p->weight;
     40             Q[++right]=p->num;
     41         }
     42     }
     43 }
     44 void dynamic()
     45 {
     46     int i;
     47     long long s1,s2,t1,t2;
     48     for(i=n;i>0;i--)
     49     {
     50         t1=t2=Q[i];
     51         s1=s2=0;
     52         int u=Q[i];
     53         for(node *p=graph[u];p;p=p->next)
     54         if(p->num!=father[u])
     55         {
     56             if(dp[p->num]+p->weight>s1)
     57             {
     58                 s2=s1;
     59                 t2=t1;
     60                 s1=dp[p->num]+p->weight;
     61                 t1=path[p->num];
     62             }
     63             else if(dp[p->num]+p->weight>s2)
     64             {
     65                 s2=dp[p->num]+p->weight;
     66                 t2=path[p->num];
     67             }
     68         }
     69         dp[u]=s1;
     70         path[u]=t1;
     71         if(s1+s2>longest_chain)
     72         {
     73             longest_chain=s1+s2;
     74             longest_node=make_pair(t1,t2);
     75         }
     76     }
     77 }
     78 int main()
     79 {
     80     int x,y,i;
     81     long long z;
     82     memset(graph,0,sizeof(graph));
     83     scanf("%d%d",&n,&m);
     84     for(i=1;i<=m;i++)
     85     {
     86         scanf("%d%d%lld",&x,&y,&z);
     87         add(x,y,z);
     88     }
     89     memset(d1,0,sizeof(d1));
     90     bfs(1,d1);
     91     dynamic();
     92     memset(d1,0,sizeof(d1));
     93     memset(d2,0,sizeof(d2));
     94     bfs(longest_node.first,d1);
     95     bfs(longest_node.second,d2);
     96     long long ans=0;
     97     for(i=1;i<=n;i++)
     98         if(min(d1[i],d2[i])>ans)
     99             ans=min(d1[i],d2[i]);
    100     printf("%lld\n",longest_chain+ans);
    101     return 0;
    102 }
  • 相关阅读:
    微博回调接口
    vue获取微博授权URL
    生成微博授权URL接口
    微博账号注册
    微博三方登录原理讲解
    使用celery异步发送短信
    celery配置与基本使用
    友情链接
    Linux无线网络设置--wpa_supplicant的使用
    wpa_supplicant介绍与使用
  • 原文地址:https://www.cnblogs.com/myoi/p/2597923.html
Copyright © 2011-2022 走看看