zoukankan      html  css  js  c++  java
  • HDU 4123 (2011 Asia FZU contest)(树形DP + 维护最长子序列)(bfs + 尺取法)

    题意:告诉一张带权图,不存在环,存下每个点能够到的最大的距离,就是一个长度为n的序列,然后求出最大值-最小值不大于Q的最长子序列的长度。

    做法1:两步,第一步是根据图计算出这个序列,大姐头用了树形DP(并不懂DP),然后就是求子序列长度,其实完全可以用RMQ爆,但是大姐头觉得会超时,于是就采用维护最大,最小值(差超过Q的时候就删掉,然后记录长度)。

    做法2:通过3次bfs求树的直径(为什么啊),然后RMQ求出所有区间的最大最小值

    时间复杂度:290ms

      1 #include <cstdio>
      2 #include <iostream>
      3 #include <sstream>
      4 #include <cmath>
      5 #include <cstring>
      6 #include <cstdlib>
      7 #include <string>
      8 #include <vector>
      9 #include <map>
     10 #include <set>
     11 #include <queue>
     12 #include <stack>
     13 #include <algorithm>
     14 using namespace std;
     15 #define ll long long
     16 #define _cle(m, a) memset(m, a, sizeof(m))
     17 #define repu(i, a, b) for(int i = a; i < b; i++)
     18 #define repd(i, a, b) for(int i = b; i >= a; i--)
     19 #define sfi(n) scanf("%d", &n)
     20 #define sfl(n) scanf("%I64d", &n)
     21 #define pfi(n) printf("%d
    ", n)
     22 #define pffi(n, m) printf("%d %d
    ", n, m)
     23 #define pfl(n) printf("%I64d
    ", n)
     24 #define MAXN 50005
     25 int n, m;
     26 int d[MAXN][2], cd[MAXN], dp[MAXN];
     27 bool vis[MAXN];
     28 struct P
     29 {
     30     int y, w;
     31     P(int _x = 0, int _w = 0) : y(_x), w(_w) {}
     32 };
     33 vector<P> v[MAXN];
     34 int p[MAXN];
     35 int num[MAXN];
     36 void dfs(int root)
     37 {
     38     if(vis[root]) return ;
     39     vis[root] = 1;
     40     int siz = v[root].size();
     41     repu(i, 0, siz) dfs(v[root][i].y);
     42     int maxn = 0;
     43     repu(i, 0, siz)
     44     if(maxn < d[v[root][i].y][0] + v[root][i].w)
     45     {
     46         maxn = d[v[root][i].y][0] + v[root][i].w;
     47         cd[root] = v[root][i].y;
     48     }
     49     d[root][0] = maxn;
     50     int c = 0;
     51     repu(i, 0, siz)
     52     if(c < d[v[root][i].y][0] + v[root][i].w && v[root][i].y != cd[root])
     53         c = d[v[root][i].y][0] + v[root][i].w;
     54     d[root][1] = c;
     55 }
     56 void DP(int root)
     57 {
     58     if(vis[root]) return ;
     59     vis[root] = 1;
     60     int siz = v[root].size();
     61     repu(i, 0, siz) if(!vis[v[root][i].y])
     62     {
     63         if(cd[root] != v[root][i].y)
     64             dp[v[root][i].y] = max(d[root][0], dp[root]) + v[root][i].w;
     65         else
     66             dp[v[root][i].y] = max(d[root][1], dp[root]) + v[root][i].w;
     67         DP(v[root][i].y);
     68     }
     69     return ;
     70 }
     71 int main()
     72 {
     73     while(sfi(n), sfi(m), (n + m))
     74     {
     75         memset(d,0,sizeof(d));
     76         memset(dp,0,sizeof(dp));
     77         memset(vis,0,sizeof(vis));
     78         memset(cd,0,sizeof(cd));
     79         repu(i, 0, n + 1) v[i].clear();
     80         int x, y, w;
     81         repu(i, 0, n - 1)
     82         {
     83             sfi(x), sfi(y), sfi(w);
     84             v[x].push_back(P(y, w));
     85         }
     86         vector<P>::iterator it;
     87         dfs(1);
     88         repu(i, 2, n + 1)
     89         if(!vis[i])
     90         {
     91             int siz = v[i].size();
     92             if(!siz) continue;
     93             int flag = 0;
     94             it = v[i].begin();
     95             for(; it != v[i].end(); it++)
     96             {
     97                 if(vis[it -> y])
     98                 {
     99                     flag = 1;
    100                     break;
    101                 }
    102             }
    103             v[it -> y].push_back(P(i, it -> w));
    104             v[i].erase(it);
    105             dfs(i);
    106         }
    107         memset(d,0,sizeof(d));
    108         memset(dp,0,sizeof(dp));
    109         memset(vis,0,sizeof(vis));
    110         memset(cd,0,sizeof(cd));
    111         repu(i, 1, n + 1)
    112         if(!vis[i]) dfs(i);
    113 
    114         memset(vis,0,sizeof(vis));
    115         repu(i, 1, n + 1)
    116         if(!vis[i]) DP(i);
    117 
    118         repu(i, 1, n + 1)
    119         p[i] = max(d[i][0], dp[i]);
    120 
    121         int Q;
    122         repu(i, 0, m)
    123         {
    124             scanf("%d", &Q);
    125             int maxnum = 0;
    126             int num = 1;
    127             int last = 1;
    128             int maxn = p[1];
    129             int minn = p[1];
    130             int maxp = 1;
    131             int minp = 1;
    132             repu(j, 2, n + 1)
    133             {
    134                 if(p[j] > maxn)
    135                 {
    136                     if(p[j] - minn > Q)
    137                     {
    138                         maxnum = max(maxnum, num);
    139                         num = 1;
    140                         j = min(minp + 1, maxp + 1);
    141                         maxn = p[j];
    142                         minn = p[j];
    143                         maxp = j;
    144                         minp = j;
    145                     }
    146                     else
    147                     {
    148                         num++;
    149                         maxn = p[j];
    150                         maxp = j;
    151                     }
    152                 }
    153                 else if(p[j] < minn)
    154                 {
    155                     if(maxn - p[j] > Q)
    156                     {
    157                         maxnum = max(maxnum, num);
    158                         num = 1;
    159                         j = min(minp + 1, maxp + 1);
    160                         maxn = p[j];
    161                         minn = p[j];
    162                         maxp = j;
    163                         minp = j;
    164                     }
    165                     else
    166                     {
    167                         num++;
    168                         minn = p[j];
    169                         minp = j;
    170                     }
    171                 }
    172                 else
    173                     num++;
    174             }
    175             maxnum = max(maxnum, num);
    176             pfi(maxnum);
    177         }
    178     }
    179     return 0;
    180 }
    树形DP+单调队列--大姐头

    时间复杂度:936ms

      1 #include <iostream>
      2 #include <cstdio>
      3 #include <cstring>
      4 #include <algorithm>
      5 #include <vector>
      6 #include <queue>
      7 #define ALL(a) a.begin(), a.end()
      8 #define clr(a, x) memset(a, x, sizeof a)
      9 #define fst first
     10 #define snd second
     11 #define pb push_back
     12 #define mp make_pair
     13 using namespace std;
     14 typedef long long LL;
     15 typedef pair<int, int> pil;
     16 #define  maxn 50050
     17 int n, m, du[maxn];
     18 int d[maxn];
     19 vector<pil> G[maxn];
     20 struct RMQ
     21 {
     22     int Dp[maxn][20];
     23     int mm[maxn];
     24     void init(int n,int b[])
     25     {
     26         mm[0] = -1;
     27         for(int i = 1; i <= n; i++)
     28         {
     29             mm[i] = ((i&(i-1)) == 0)?mm[i-1]+1:mm[i-1];
     30             Dp[i][0] = b[i];
     31         }
     32         for(int j = 1; j <= mm[n]; j++)
     33             for(int i = 1; i + (1<<j) -1 <= n; i++)
     34                 Dp[i][j] = max(Dp[i][j-1],Dp[i+(1<<(j-1))][j-1]);
     35     }
     36     int rmq(int x,int y)
     37     {
     38         int k = mm[y-x+1];
     39         return max(Dp[x][k],Dp[y-(1<<k)+1][k]);
     40     }
     41 } Min,Max;
     42 int dis[maxn]= {0};
     43 bool vis[maxn]= {0};
     44 queue<int> q;
     45 
     46 int bfs(int u)
     47 {
     48     clr(dis, 0);
     49     clr(vis, 0);
     50     int ans=0, Max=0;
     51     q.push(u);
     52     dis[u]=0, vis[u]=1;
     53     while(!q.empty())
     54     {
     55         int u=q.front();
     56         q.pop();
     57         if(dis[u]>Max)
     58             Max=dis[ans=u];
     59         for(int i=0; i<G[u].size(); i++)
     60         {
     61             pil t=G[u][i];
     62             int v=t.fst, w=t.snd;
     63             if(vis[v])continue ;
     64             dis[v]=dis[u]+w;
     65             vis[v]=true;
     66             q.push(v);
     67         }
     68     }
     69     for(int i=1; i<=n; i++)
     70         d[i]=max(d[i], dis[i]);
     71     return ans;
     72 }
     73 
     74 int main()
     75 {
     76     while(~scanf("%d%d", &n, &m) && n+m)
     77     {
     78         for(int i=1; i<=n; i++)
     79         {
     80             G[i].clear();
     81             d[i]=0;
     82         }
     83         for(int i=0; i<n-1; i++)
     84         {
     85             int u, v, w;
     86             scanf("%d%d%d", &u, &v, &w);
     87             G[u].pb(mp(v, w));
     88             G[v].pb(mp(u, w));
     89         }
     90         ///每次bfs都是求出所有点到起点的距离(只有一条路,没有最大最小)
     91         ///然后返回与起点距离最大的点MAX,再求一次所有点与MAX距离最大的点。
     92         ///求3次就可以把每个点的最大距离求出来
     93         bfs(bfs(bfs(1)));
     94         Max.init(n, d);
     95         ///从最大值到最小值换成相反数即可
     96         for(int i=1; i<=n; i++)
     97             d[i]=-d[i];
     98         Min.init(n, d);
     99         while(m--)
    100         {
    101             int q, ans=0;
    102             scanf("%d", &q);
    103             int ok = 0;
    104             for(int i=1, j=1; i<=n; i++)
    105             {
    106                 ///原来是尺取法,傻傻的我以为完全暴力
    107                 ///j只是从1开始,然后只是增加,一直到等于n
    108                 while(j<=n && Max.rmq(i, j)+Min.rmq(i, j)<=q)
    109                     ans=max(ans, j-i+1), j++;
    110             }
    111             printf("%d
    ", ans);
    112         }
    113     }
    114     return 0;
    115 }
    3次bfs + 尺取法----SX神
  • 相关阅读:
    GIS单词汇总
    ArcGIS Server 开发初步 自定义工具
    ArcGIS Server 9.2 实现基于web浏览器的在线编辑
    控制图层是否显示的方法
    地图缓存与瓦片切割步骤
    汉字转拼音缩写(VB版)
    VB的Winsock控件GetData方法获取汉字乱码解决方法
    柱状专题图实现例子
    汉字转拼音缩写(C#版)
    ArcGIS Server .NET ADF中的AJAX之深入浅出/CallbackResult详解
  • 原文地址:https://www.cnblogs.com/ACMERY/p/4711849.html
Copyright © 2011-2022 走看看