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

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

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

时间复杂度:290ms

 #include <cstdio>
#include <iostream>
#include <sstream>
#include <cmath>
#include <cstring>
#include <cstdlib>
#include <string>
#include <vector>
#include <map>
#include <set>
#include <queue>
#include <stack>
#include <algorithm>
using namespace std;
#define ll long long
#define _cle(m, a) memset(m, a, sizeof(m))
#define repu(i, a, b) for(int i = a; i < b; i++)
#define repd(i, a, b) for(int i = b; i >= a; i--)
#define sfi(n) scanf("%d", &n)
#define sfl(n) scanf("%I64d", &n)
#define pfi(n) printf("%d\n", n)
#define pffi(n, m) printf("%d %d\n", n, m)
#define pfl(n) printf("%I64d\n", n)
#define MAXN 50005
int n, m;
int d[MAXN][], cd[MAXN], dp[MAXN];
bool vis[MAXN];
struct P
{
int y, w;
P(int _x = , int _w = ) : y(_x), w(_w) {}
};
vector<P> v[MAXN];
int p[MAXN];
int num[MAXN];
void dfs(int root)
{
if(vis[root]) return ;
vis[root] = ;
int siz = v[root].size();
repu(i, , siz) dfs(v[root][i].y);
int maxn = ;
repu(i, , siz)
if(maxn < d[v[root][i].y][] + v[root][i].w)
{
maxn = d[v[root][i].y][] + v[root][i].w;
cd[root] = v[root][i].y;
}
d[root][] = maxn;
int c = ;
repu(i, , siz)
if(c < d[v[root][i].y][] + v[root][i].w && v[root][i].y != cd[root])
c = d[v[root][i].y][] + v[root][i].w;
d[root][] = c;
}
void DP(int root)
{
if(vis[root]) return ;
vis[root] = ;
int siz = v[root].size();
repu(i, , siz) if(!vis[v[root][i].y])
{
if(cd[root] != v[root][i].y)
dp[v[root][i].y] = max(d[root][], dp[root]) + v[root][i].w;
else
dp[v[root][i].y] = max(d[root][], dp[root]) + v[root][i].w;
DP(v[root][i].y);
}
return ;
}
int main()
{
while(sfi(n), sfi(m), (n + m))
{
memset(d,,sizeof(d));
memset(dp,,sizeof(dp));
memset(vis,,sizeof(vis));
memset(cd,,sizeof(cd));
repu(i, , n + ) v[i].clear();
int x, y, w;
repu(i, , n - )
{
sfi(x), sfi(y), sfi(w);
v[x].push_back(P(y, w));
}
vector<P>::iterator it;
dfs();
repu(i, , n + )
if(!vis[i])
{
int siz = v[i].size();
if(!siz) continue;
int flag = ;
it = v[i].begin();
for(; it != v[i].end(); it++)
{
if(vis[it -> y])
{
flag = ;
break;
}
}
v[it -> y].push_back(P(i, it -> w));
v[i].erase(it);
dfs(i);
}
memset(d,,sizeof(d));
memset(dp,,sizeof(dp));
memset(vis,,sizeof(vis));
memset(cd,,sizeof(cd));
repu(i, , n + )
if(!vis[i]) dfs(i); memset(vis,,sizeof(vis));
repu(i, , n + )
if(!vis[i]) DP(i); repu(i, , n + )
p[i] = max(d[i][], dp[i]); int Q;
repu(i, , m)
{
scanf("%d", &Q);
int maxnum = ;
int num = ;
int last = ;
int maxn = p[];
int minn = p[];
int maxp = ;
int minp = ;
repu(j, , n + )
{
if(p[j] > maxn)
{
if(p[j] - minn > Q)
{
maxnum = max(maxnum, num);
num = ;
j = min(minp + , maxp + );
maxn = p[j];
minn = p[j];
maxp = j;
minp = j;
}
else
{
num++;
maxn = p[j];
maxp = j;
}
}
else if(p[j] < minn)
{
if(maxn - p[j] > Q)
{
maxnum = max(maxnum, num);
num = ;
j = min(minp + , maxp + );
maxn = p[j];
minn = p[j];
maxp = j;
minp = j;
}
else
{
num++;
minn = p[j];
minp = j;
}
}
else
num++;
}
maxnum = max(maxnum, num);
pfi(maxnum);
}
}
return ;
}

树形DP+单调队列--大姐头

时间复杂度:936ms

 #include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
#include <queue>
#define ALL(a) a.begin(), a.end()
#define clr(a, x) memset(a, x, sizeof a)
#define fst first
#define snd second
#define pb push_back
#define mp make_pair
using namespace std;
typedef long long LL;
typedef pair<int, int> pil;
#define maxn 50050
int n, m, du[maxn];
int d[maxn];
vector<pil> G[maxn];
struct RMQ
{
int Dp[maxn][];
int mm[maxn];
void init(int n,int b[])
{
mm[] = -;
for(int i = ; i <= n; i++)
{
mm[i] = ((i&(i-)) == )?mm[i-]+:mm[i-];
Dp[i][] = b[i];
}
for(int j = ; j <= mm[n]; j++)
for(int i = ; i + (<<j) - <= n; i++)
Dp[i][j] = max(Dp[i][j-],Dp[i+(<<(j-))][j-]);
}
int rmq(int x,int y)
{
int k = mm[y-x+];
return max(Dp[x][k],Dp[y-(<<k)+][k]);
}
} Min,Max;
int dis[maxn]= {};
bool vis[maxn]= {};
queue<int> q; int bfs(int u)
{
clr(dis, );
clr(vis, );
int ans=, Max=;
q.push(u);
dis[u]=, vis[u]=;
while(!q.empty())
{
int u=q.front();
q.pop();
if(dis[u]>Max)
Max=dis[ans=u];
for(int i=; i<G[u].size(); i++)
{
pil t=G[u][i];
int v=t.fst, w=t.snd;
if(vis[v])continue ;
dis[v]=dis[u]+w;
vis[v]=true;
q.push(v);
}
}
for(int i=; i<=n; i++)
d[i]=max(d[i], dis[i]);
return ans;
} int main()
{
while(~scanf("%d%d", &n, &m) && n+m)
{
for(int i=; i<=n; i++)
{
G[i].clear();
d[i]=;
}
for(int i=; i<n-; i++)
{
int u, v, w;
scanf("%d%d%d", &u, &v, &w);
G[u].pb(mp(v, w));
G[v].pb(mp(u, w));
}
///每次bfs都是求出所有点到起点的距离(只有一条路,没有最大最小)
///然后返回与起点距离最大的点MAX,再求一次所有点与MAX距离最大的点。
///求3次就可以把每个点的最大距离求出来
bfs(bfs(bfs()));
Max.init(n, d);
///从最大值到最小值换成相反数即可
for(int i=; i<=n; i++)
d[i]=-d[i];
Min.init(n, d);
while(m--)
{
int q, ans=;
scanf("%d", &q);
int ok = ;
for(int i=, j=; i<=n; i++)
{
///原来是尺取法,傻傻的我以为完全暴力
///j只是从1开始,然后只是增加,一直到等于n
while(j<=n && Max.rmq(i, j)+Min.rmq(i, j)<=q)
ans=max(ans, j-i+), j++;
}
printf("%d\n", ans);
}
}
return ;
}

3次bfs + 尺取法----SX神

HDU 4123 (2011 Asia FZU contest)(树形DP + 维护最长子序列)(bfs + 尺取法)的更多相关文章

  1. HDU 4123 Bob’s Race(树形DP,rmq)

    Bob’s Race Time Limit: 5000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total ...

  2. HDU 1520.Anniversary party 基础的树形dp

    Anniversary party Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others ...

  3. HDU 1054 Strategic Game(最小点覆盖+树形dp)

    题目链接:http://acm.hust.edu.cn/vjudge/contest/view.action?cid=106048#problem/B 题意:给出一些点相连,找出最小的点数覆盖所有的 ...

  4. HDU 3586 Information Disturbing(二分+树形dp)

    http://acm.split.hdu.edu.cn/showproblem.php?pid=3586 题意: 给定一个带权无向树,要切断所有叶子节点和1号节点(总根)的联系,每次切断边的费用不能超 ...

  5. HDU 5682 zxa and leaf 二分 树形dp

    zxa and leaf 题目连接: http://acm.hdu.edu.cn/showproblem.php?pid=5682 Description zxa have an unrooted t ...

  6. HDU 6201 2017沈阳网络赛 树形DP或者SPFA最长路

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6201 题意:给出一棵树,每个点有一个权值,代表商品的售价,树上每一条边上也有一个权值,代表从这条边经过 ...

  7. HDU 6201 transaction transaction transaction(树形DP)

    transaction transaction transaction Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 132768/1 ...

  8. TTTTTTTTTTT hdu 1520 Anniversary party 生日party 树形dp第一题

    Anniversary party Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others ...

  9. hdu 4612 Warm up 双连通+树形dp思想

    Warm up Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65535/65535 K (Java/Others) Total S ...

随机推荐

  1. python中的正则表达式(re模块)

    一.简介 正则表达式本身是一种小型的.高度专业化的编程语言,而在python中,通过内嵌集成re模块,程序媛们可以直接调用来实现正则匹配.正则表达式模式被编译成一系列的字节码,然后由用C编写的匹配引擎 ...

  2. hibernate的二级缓存

    缓存(Cache): 计算机领域非常通用的概念.它介于应用程序和永久性数据存储源(如硬盘上的文件或者数据库)之间,其作用是降低应用程序直接读写永久性数据存储源的频率,从而提高应用的运行性能.缓存中的数 ...

  3. JAVA基础知识之JDBC——使用ResultSetMetaData分析结果集

    通过ResultSetMetaData可以对ResultSet进行分析,获取ResultSet里包含了哪些数据列,以及每个列的数据类型. ResultSet中包含了一个getMetaData()方法, ...

  4. [Scrapy] Mac安装Scrapy

    Mac安装Scrapy Mac版本 10.11 El Captain. 前一段想在Mac上用Scrapy,各种问题.有一个不错的工具:Anaconda. 安装Anaconda 下载地址 我还是下pyt ...

  5. CSS3的chapter3

    CSS的常用样式分为几大类: 字体样式(font,color, text-decoration ,text-shadow) 元素样式(width,height,margin,padding,opaci ...

  6. C语言位操作(转)

    http://www.cnblogs.com/cpoint/category/524132.html  

  7. Flex 文本控件实现自定义复制粘贴

    由于添加了自定义右键菜单,导致Textinput控件默认的右键复制粘贴功能被屏蔽了.最后通过JS脚本实现这个功能,参考代码如下 <?xml version="1.0" enc ...

  8. iOS AFNetworking中cookie的读取与设置

    参考: http://blog.csdn.net/zhaoxy_thu/article/details/20532879 实际上AFNetworking中并没有专门针对cookie封装的代码,但是由于 ...

  9. Python之No module named setuptools 安装pip

    早上运行程序的时候发现没有引入相应的module,然后使用pip去安装的时候发现自己没有在安装pip,于是在自己的软件群里边找见了pip安装包,在pip的解压目录下运行python setup.py ...

  10. 如何浏览并管理 Outlook 邮件?

    当你的邮件多起来的时候你就不得不考虑这个问题了,如何处理各种邮件? 如何浏览并管理 Outlook 邮件? 待续~