Gym 101147J Whistle's New Car(dfs)
2017-05-26 15:53
302 查看
https://vjudge.net/problem/Gym-101147J
题意:
有n个城市,每个城市有一个权值,表示在这个城市的加油站可以加多少油。
现在要计算每个城市i,有多少个城市j可以到达它:
① j 是 i 的子树。
② 在城市 j 加满Xj的油后不再加油能到达 i 城市。
思路:
我们从根结点出发,dfs整棵树,在dfs的过程中,我们维护一个道路长度的和sum[],sum[j]就是1到第j个城市的路径之和。
假如我们现在dfs到了第j个城市v,此时1~j的路径之和就是sum[j],然后sum[j]-x[v]就是从v城市出发所能到达的最远距离。
接下来二分查找计算出从v出发在这条路径上所能到达的最远的城市。它所能到达的城市都需要+1。
最后把子节点的个数加到父节点上即可。
题意:
有n个城市,每个城市有一个权值,表示在这个城市的加油站可以加多少油。
现在要计算每个城市i,有多少个城市j可以到达它:
① j 是 i 的子树。
② 在城市 j 加满Xj的油后不再加油能到达 i 城市。
思路:
我们从根结点出发,dfs整棵树,在dfs的过程中,我们维护一个道路长度的和sum[],sum[j]就是1到第j个城市的路径之和。
假如我们现在dfs到了第j个城市v,此时1~j的路径之和就是sum[j],然后sum[j]-x[v]就是从v城市出发所能到达的最远距离。
int pos=lower_bound(sum,sum+ret+1,sum[ret]-x[v])-sum;
接下来二分查找计算出从v出发在这条路径上所能到达的最远的城市。它所能到达的城市都需要+1。
最后把子节点的个数加到父节点上即可。
#include<iostream> #include<algorithm> #include<cstring> #include<cstdio> #include<vector> #include<stack> #include<queue> #include<cmath> #include<map> using namespace std; typedef long long LL; typedef pair<int,LL> pll; const int maxn=500000+5; int n; LL x[maxn]; int vis[maxn]; LL sum[maxn]; int num[maxn]; int cnt[maxn]; int ret; vector<pll> G[maxn]; void dfs(int u) { vis[u]=1; for(int i=0;i<G[u].size();i++) { int v=G[u][i].first; int w=G[u][i].second; if(vis[v]) continue; sum[ret]=sum[ret-1]+w; num[ret]=v; //路径上第ret城市为v int pos=lower_bound(sum,sum+ret+1,sum[ret]-x[v])-sum;//v出发能到达的最远的城市 if(pos<ret)//如果能到达父结点城市 { cnt[u]++; //父节点城市数量+1 cnt[num[pos-1]]--; //这个一定要减,不然后面子节点的数加到父节点的时候,父节点就多加了 } ret++; dfs(v); ret--; cnt[u]+=cnt[v]; } } int main() { // freopen("car.in","r",stdin); //freopen("D:\\input.txt","r",stdin); int T; scanf("%d",&T); while(T--) { scanf("%d",&n); for(int i=0;i<=n;i++) G[i].clear(); for(int i=1;i<=n;i++) scanf("%lld",&x[i]); for(int i=1;i<n;i++) { int u,v; LL d; scanf("%d%d%lld",&u,&v,&d); G[u].push_back(make_pair(v,d)); G[v].push_back(make_pair(u,d)); } memset(vis,0,sizeof(vis)); memset(cnt,0,sizeof(cnt)); ret=1; sum[0]=0; //1~路径上第j个城市的距离和 num[0]=1; dfs(1); //从根结点出发遍历 for(int i=1;i<=n;i++) printf("%d%c",cnt[i],i!=n?' ':'\n'); } return 0; }
相关文章推荐
- Gym - 100221D 一题一直没过的dfs,,应该是纯手动码?
- 【找规律】【DFS】Gym - 101174H - Pascal's Hyper-Pyramids
- [codeforces] Gym - 101246G Revolutionary Roads (DFS)
- Gym 100646 You’ll be Working on the Railroad dfs
- GYM 100796 K.Profact(dfs)
- H - House of Representatives-Gym 100496H-dfs
- A - GREAT+SWERC=PORTO Gym - 100783A 简单dfs
- 【递推】【DFS】【枚举】Gym - 101246C - Explode 'Em All
- Gym-101615D Rainbow Roads 树的DFS序 差分数组
- 【codeforces gym 100187J】 【dfs判连通】Deck Shuffling 【给你一堆牌和一些洗牌机,后者可以改变牌的顺序,问你能不能把数字为x的牌洗到第一个位置。】
- Personal programming language Gym - 100741B(dfs)
- Gym - 101257A The Fault in Our Cubes【DFS】
- GYM 101086 J.Smooth Developer(dfs)
- codeforces-gym-100187-J【dfs】
- GYM 100796 C.Minimax Tree(dfs)
- Codeforces Gym 100338I TV Show 傻逼DFS,傻逼题
- Gym 100962J Jimi Hendrix (DFS + 树形dp)
- 【DFS】【枚举】Gym - 101246G - Revolutionary Roads
- CodeForces Gym 100989L Plus or Minus (A) DFS
- Gym 100512D Dynamic LCA ((LCA 在线算法DFS+ST) + 分类讨论!!)