文章标题
来源:互联网 发布:淘宝怎样卖虚拟物品 编辑:程序博客网 时间:2024/06/09 14:46
比赛的时候以为这是一道动态维护树的中心,看了题解发现自己想错了,公共祖先的题目确实是少
这次学习了一下set
发现有很多使用简便的地方
#include <cstdio>#include <cstring>#include <algorithm>#include <vector>#include <set>#include <utility>using namespace std;#define N 111111#define iter set<int>::iteratorint par[N][20];int depth[N];int dis[N];int n,m;int p[N];int vis[N];int cnt;int dfn[N];vector<pair<int,int>>edge[N];set<int> ans;void dfs(int u,int fa){ dfn[++cnt]=u; p[u]=cnt; //printf("%d %d\n",u,fa); for(int i=1;i<18;i++){ //寻找他的十八辈祖宗 par[u][i]=par[par[u][i-1]][i-1]; } for(int i=0;i<edge[u].size();i++){ int v=edge[u][i].first; if(fa==v) continue ; depth[v] = depth[u] + 1; dis[v] = dis[u] + edge[u][i].second; par[v][0] = u; dfs(v,u); }}int lca(int u,int v){ if(depth[u]>depth[v]) swap(u,v); for(int k=0;k<18;k++){ if((depth[v]-depth[u])>>k&1){ v = par[v][k]; } } if(v==u) return u; for(int k=17;k>=0;k--){ if(par[u][k]!=par[v][k]){ u=par[u][k]; v=par[v][k]; } } return par[u][0];}int tot;int add(int u){ if (ans.empty()) return 0; int x, y; //寻找与u相邻的dfs序点 iter it = ans.lower_bound(p[u]); iter itx = it; itx--; if (it == ans.end() || it == ans.begin()) { it = ans.begin(); itx = ans.end(); itx--; } y = (*it); x = (*itx); y = dfn[y]; x = dfn[x]; return dis[u] - dis[lca(x, u)] - dis[lca(y, u)] + dis[lca(x, y)];}void init(){ for(int i=1;i<=n;i++){ edge[i].clear(); } memset(vis,0,sizeof(vis)); memset(dfn,0,sizeof(dfn)); memset(p,0,sizeof(p)); memset(par,0,sizeof(par)); memset(dis,0,sizeof(dis)); memset(depth,0,sizeof(depth)); cnt=0; ans.clear();}int main(){ int T; int cas = 0; scanf("%d",&T); while(T--){ scanf("%d%d",&n,&m); init(); int x,y,z; for(int i=1;i<n;i++){ scanf("%d%d%d",&x,&y,&z); edge[x].push_back(make_pair(y,z)); edge[y].push_back(make_pair(x,z)); } /* for(int i=1;i<=n;i++){ printf("%d :",i); for(int j=0;j<edge[i].size();j++){ printf("%d ",edge[i][j].first); } puts(""); } */ dis[1]=0; depth[1]=1; dfs(1,-1); /* for(int i=1;i<=n;i++){ printf("%d %d %d\n",i,dis[i],par[i][0]); } */ int sum=0; printf("Case #%d:\n",++cas); for(int i=1;i<=m;i++){ scanf("%d%d",&x,&y); int tmp; if(x==1){ if(!vis[y]){ vis[y]=1; if (ans.size() == 0) { ans.insert(p[y]); } else { tmp = add(y); ans.insert(p[y]); sum += tmp; } } } else{ if(vis[y]){ vis[y] = 0; ans.erase(p[y]); if (!ans.empty()) { sum -= add(y); } } } printf("%d\n",sum); } }}
0 0
- 文章标题文章标题文章标题文章标题文章标题文章标题文章标题文章标题文章标题文章标题文章标题文章标题文章标题文章标题文章标题文章标题文章标题
- 文章标题
- 文章标题
- 文章标题
- 文章标题 文章标题 文章标题 文章标题
- 文章标题
- 文章标题
- 文章标题
- 文章标题
- 文章标题
- 文章标题
- 文章标题
- 文章标题
- 文章标题
- 文章标题
- 文章标题
- 文章标题
- 文章标题
- 【牛腩新闻发布系统】牛腩发布,其实我也行
- uva 10806 Dijkstra, Dijkstra. (最小费最大流)
- BASH中的内置变量
- 配置Jenkins邮件
- Java中Timer的用法
- 文章标题
- 链表的反转问题(Reverse Linked List)
- HSP Profile注册过程(未完成)
- KAFKA学习总结
- 深入理解kafka设计原理
- ACM计算几何推荐
- 关于正则表达式
- PayPal - (REST 框架 PHP) Express Checkout(EC)快捷支付使用说明
- [C++设计模式] composite 组合模式