题意:告诉一张带权图,不存在环,存下每个点能够到的最大的距离,就是一个长度为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. (转)将cocos2dx项目从VS移植到Eclipse

    本文转自:http://www.cnblogs.com/Z-XML/p/3349518.html 引言:我们使用cocos2d-x引擎制作了一款飞行射击游戏,其中创新性地融入了手势识别功能.但是我 们 ...

  2. Entity Framework 第十篇 条件查询

    业务类中 我们根据条件来动态的查询 创建IQueryable接口 public IQueryable<TEntity> GetQueryable() { IQueryable<TEn ...

  3. 字典的循环和if语句

    字典是键-值(key-value)存储,循环的时候也是以键为对象 d = {'Michael': 95, 'Tracy': 85,'Bob': 75} for x in d : print x 输出结 ...

  4. Mysql新知识点150928

    1.select distinct(DATE_FORMAT(updatetime,'%Y-%m')) as updatetime from barcode where pid!=0 order by ...

  5. Codeforces Round #384 (Div. 2)A,B,C,D

    A. Vladik and flights time limit per test 2 seconds memory limit per test 256 megabytes input standa ...

  6. 练习一:GitHub Desktop下载及使用

    推荐使用Git for Windows,官方网站 https://git-for-windows.github.io/ 这里有我写的Git和Github教程:http://www.cnblogs.co ...

  7. 机器学习职位 & 面经

    http://www.cnblogs.com/peileyuan/p/4775453.html <浅谈机器学习的职业发展方向> http://blog.sina.com.cn/s/blog ...

  8. 使用Eclipse创建maven项目

    前提:Eclipse中安装了maven插件,或者Eclipse版本在Mars以上(自集成maven) 1.new project --maven project 2.默认点击next 3.选择构建类型 ...

  9. Android Material适配 为控件设置指定背景色和点击波纹效果

    Android Material适配 为控件设置指定背景色和点击波纹效果,有需要的朋友可以参考下. 大部分时候,我们都需要为控件设置指定背景色和点击效果 4.x以下可以使用selector,5.0以上 ...

  10. Windows Store App 插值动画

    插值动画支持DoubleAnimation.ColorAnimation和PointAnimation类型的动画.其中比较常用的是DoubleAnimation动画,它可以用来控制界面元素的Doubl ...