dfs序(HDU 5296,Annoying problem)
来源:互联网 发布:创新创业网络课答案 编辑:程序博客网 时间:2024/06/05 00:48
HDU 5296,Annoying problem
如果不好模拟,那么可以考虑计算出来。
dfs序配合二分是树上常用的找特殊点的工具。时间戳的记录使得我们可以快速地找到满足范围限制的点。(夹在某两个时间之间的点)
代码:
#include<stdio.h>#include<vector>#include<set>using namespace std;typedef long long ll;const int maxn = 100010;const int maxe = 20;typedef pair<int,int>pii;int n,q;vector<int>G[maxn];vector<int>W[maxn];int in[maxn];int rk[maxn];int tim;int dp[maxn][maxe];int dep[maxn];ll dis[maxn][maxe];set<pii>s;void dfs(int u,int f,int d){ dep[u]=d; in[u]=++tim; rk[tim]=u; dp[u][0]=f; for(int i=1;(1<<i)<n;i++) dp[u][i]=-1; for(int i=0;i<(int)G[u].size();i++) { int v = G[u][i]; if(v==f) continue; dis[v][0]=W[u][i]; dfs(v,u,d+1); }}ll dist(int u,int v){ if(dep[u]<dep[v]) swap(u,v); int log; for(log=1;(1<<log)<=dep[u];log++);log--; ll sum=0; for(int i=log;i>=0;i--) if(dep[u]-(1<<i)>=dep[v]) { sum+=dis[u][i]; u=dp[u][i]; } if(u==v) return sum; for(int i=log;i>=0;i--) if(dp[u][i]!=-1&&dp[u][i]!=dp[v][i]) { sum+=dis[u][i]; u=dp[u][i]; sum+=dis[v][i]; v=dp[v][i]; } sum+=dis[u][0]; sum+=dis[v][0]; return sum;}void solve(){ scanf("%d %d",&n,&q); for(int i=1;i<=n;i++) { G[i].clear(); W[i].clear(); } tim=0; for(int i=1;i<n;i++) { int u,v,w; scanf("%d %d %d",&u,&v,&w); G[u].push_back(v); W[u].push_back(w); G[v].push_back(u); W[v].push_back(w); } dfs(1,-1,0); for(int j=1;(1<<j)<n;j++) for(int i=1;i<=n;i++) if(dp[i][j-1]!=-1) { dp[i][j]=dp[dp[i][j-1]][j-1]; dis[i][j]=dis[i][j-1]+dis[dp[i][j-1]][j-1]; } s.clear(); int x,y; ll sum=0; while(q--) { scanf("%d %d",&x,&y); if(x==1) { if(s.size()==0) { s.insert(make_pair(in[y],y)); puts("0"); continue; } } if(x==2) { if(!s.count(make_pair(in[y],y))) { printf("%lld\n",sum); continue; } s.erase(make_pair(in[y],y)); if(s.size()<2) { sum=0; puts("0"); continue; } } int u,v; if(s.size()==0) s.insert(make_pair(in[y],y)); { set<pii>::iterator it = s.lower_bound(make_pair(in[y],y)),it2; if(it==s.end()||it==s.begin()) { u = s.begin()->second; v = (--s.end())->second; } else { it2=it; --it2; u = it->second; v = it2->second; } } if(x==1) { sum+=(dist(u,y)+dist(v,y)-dist(u,v))/2; s.insert(make_pair(in[y],y)); } else sum-=(dist(u,y)+dist(v,y)-dist(u,v))/2; printf("%lld\n",sum); }}int main(){ int T; scanf("%d",&T); for(int t=1;t<=T;t++) { printf("Case #%d:\n",t); solve(); } return 0;}
0 0
- dfs序(HDU 5296,Annoying problem)
- HDU 5296 Annoying problem dfs序+lca
- HDU 5296 Annoying problem (树状数组+dfs序+倍增)
- [HDU 5296] Annoying problem (DFS序性质+LCA)
- HDU 5296 Annoying problem(LCA模板+树的dfs序心得)
- HDU 5296 Annoying problem
- HDU 5296 Annoying problem
- HDU 5296 Annoying problem
- hdu 5296 Annoying problem
- hdu 5296 Annoying problem(15多校第一场1009)(在线lca+dfs序)
- 多校第一场 1009 hdu 5296 Annoying problem(dfs序+在线倍增lca)
- hdu 5296 Annoying problem(LCA)
- 【LCA】HDU 5296 Annoying problem
- hdu 5296 Annoying problem (LCA)
- HDU 5296 Annoying problem(点到树链的距离+LCA)
- HDU 5296 Annoying problem LCA+树状数组
- 【HDU】5296 Annoying problem【树链剖分+分类讨论】
- HDOJ 5296 Annoying problem
- 蓝桥杯 算法训练 表达式的计算(中缀转后缀表达式求值)
- D
- Centos7网络设置
- Version 1.7.0_121 of the JVM is not suitable for this product. Version: 1.8
- 安卓内存泄露几种常见形式及解决方案
- dfs序(HDU 5296,Annoying problem)
- 未来的程序员还会有今天的收入吗?
- 最长回文子串 C++
- Android视图SurfaceView
- HDU 1039 Easier Done Than Said?
- Hibernate的autocommit问题
- response.setContentType与 request.setCharacterEncoding 区别
- Android存储系统之架构篇
- Golang 闭包的理解