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 }

posted on 2012-07-18 18:07  myoi  阅读(442)  评论(0编辑  收藏  举报

导航