第十二周 11.16---11.22
2015-11-16 22:45
281 查看
新的一周>_<
---------11.16
补题--
越来越觉得笨得可以了--
----------11.17
补了南阳最短路那题
那样的转化还是不是很懂---
---- wo shi sb----
---------11.18
补了南阳的 修乒乓器室,台球室那题dp
全程看题解---还是觉得理解得好艰难啊--
---------11.19
补了多校第一场的一道题
hdu 5296
给出一棵树,然后有2个操作
1 x 是将 x 节点 加入 集合 中
2 x 是将 x 节点从集合中删除
为了使集合中的任意两个点都是联通的,至少需要加的边权
-----没有思路-----------------
看的题解了
假设一条链的两端 是 x 和 y ,一个节点 u
u 到 链 x---y 的距离大概是这样来算的
u 到 x 端的距离 dis[u] + dis[x] - 2dis[Lca(x,u)]
u 到 y 端的距离 dis[u] + dis[y] - 2dis[Lca(y,u)]
多算了 x 到 y 的距离 dis[x] + dis[y] - 2dis[Lca(x,y)]
所以 u 到 链 x --- y 的距离为
{ dis[u] + dis[x] - 2dis[Lca(x,u)] + dis[u] + dis[y] - 2dis[Lca(y,u)] - dis[x] + dis[y] - 2dis[Lca(x,y)]}/2
然后,就是x,y端的选择
题解说根据 dfn 来选
选择节点 u 左边和右边挨得最近 的 x ,y
如果没找到的话,就分别是 最小的,最大的
可是为什么是这样,,,,
画了几下,貌似这样的距离是更小的,,,,
自己先用的set的lower_bound 和 upper_bound来找 左右两边的
可是写搓了
后来看了别人的代码
发现是漏了 在 添加操作的时候,那个节点本来就在集合里面
在删除的时候,那个节点本来就不在集合里面
这两种情况
然后,,还学到了 set的重载,从大到小的放元素,直接找不到就是 到 了 set.end()
感觉比自己这样一边找到 begin(),一边找到 end 方便些
View Code
---------11.16
补题--
越来越觉得笨得可以了--
----------11.17
补了南阳最短路那题
那样的转化还是不是很懂---
---- wo shi sb----
---------11.18
补了南阳的 修乒乓器室,台球室那题dp
全程看题解---还是觉得理解得好艰难啊--
---------11.19
补了多校第一场的一道题
hdu 5296
给出一棵树,然后有2个操作
1 x 是将 x 节点 加入 集合 中
2 x 是将 x 节点从集合中删除
为了使集合中的任意两个点都是联通的,至少需要加的边权
-----没有思路-----------------
看的题解了
假设一条链的两端 是 x 和 y ,一个节点 u
u 到 链 x---y 的距离大概是这样来算的
u 到 x 端的距离 dis[u] + dis[x] - 2dis[Lca(x,u)]
u 到 y 端的距离 dis[u] + dis[y] - 2dis[Lca(y,u)]
多算了 x 到 y 的距离 dis[x] + dis[y] - 2dis[Lca(x,y)]
所以 u 到 链 x --- y 的距离为
{ dis[u] + dis[x] - 2dis[Lca(x,u)] + dis[u] + dis[y] - 2dis[Lca(y,u)] - dis[x] + dis[y] - 2dis[Lca(x,y)]}/2
然后,就是x,y端的选择
题解说根据 dfn 来选
选择节点 u 左边和右边挨得最近 的 x ,y
如果没找到的话,就分别是 最小的,最大的
可是为什么是这样,,,,
画了几下,貌似这样的距离是更小的,,,,
自己先用的set的lower_bound 和 upper_bound来找 左右两边的
可是写搓了
后来看了别人的代码
发现是漏了 在 添加操作的时候,那个节点本来就在集合里面
在删除的时候,那个节点本来就不在集合里面
这两种情况
然后,,还学到了 set的重载,从大到小的放元素,直接找不到就是 到 了 set.end()
感觉比自己这样一边找到 begin(),一边找到 end 方便些
#include<cstdio> #include<cstring> #include<iostream> #include<algorithm> #include<set> #include<vector> using namespace std; typedef long long LL; const int MAXN = 4e5+5; const int MAX_LOG = 32; int n,q,ecnt,tot; int first[MAXN],dfn[MAXN],ddfn[MAXN]; int fa[MAX_LOG][MAXN],dep[MAXN]; int dis[MAXN]; struct Edge{ int u,v,nxt,w; }e[MAXN]; void init(){ memset(first,-1,sizeof(first)); ecnt = tot = 0; } void Add_edge(int u,int v,int w){ e[ecnt].u = u; e[ecnt].v = v; e[ecnt].w = w; e[ecnt].nxt = first[u]; first[u] = ecnt++; } void Dfs(int p,int pre,int d){ dfn[p] = ++tot; ddfn[tot] = p; dep[p] = d; fa[0][p] = pre; for(int i = first[p];~i;i = e[i].nxt){ int v = e[i].v; if(v == pre) continue; dis[v] = dis[p] + e[i].w; Dfs(v,p,d+1); } } void Pre(){ dis[1] = 0; Dfs(1,-1,0); for(int k = 0;k+1 < MAX_LOG;++k){ for(int v = 1;v <= n;++v){ if(fa[k][v] < 0) fa[k+1][v] = -1; else fa[k+1][v] = fa[k][fa[k][v]]; } } } int Lca(int u,int v){ if(dep[u] > dep[v]) swap(u,v); for(int k = MAX_LOG-1;k >= 0;--k){ if((dep[v]-dep[u]) & (1<<k)) v = fa[k][v]; } if(u == v) return u; for(int k = MAX_LOG-1;k >= 0;--k){ if(fa[k][u] != fa[k][v]){ u = fa[k][u]; v = fa[k][v]; } } return fa[0][u]; } void solve(){ set<int> s; set<int>::iterator l,it,r,itt; int ans = 0,x,y; for(int i = 1;i <= q;i++){ int cmd,u; scanf("%d %d",&cmd,&u); if(cmd == 1){ if(s.size() == 0){ puts("0"); s.insert(dfn[u]); continue; } if(s.find(dfn[u]) != s.end()){ printf("%d\n",ans); s.insert(dfn[u]); continue; } l = s.lower_bound(dfn[u]); r = s.upper_bound(dfn[u]); if(l == s.begin() || r == s.end()){ l = s.begin();r = s.end();r--; } else l--; x = ddfn[*l];y = ddfn[*r]; // printf("x = %d y = %d\n",x,y); ans += dis[u] - dis[Lca(x,u)] - dis[Lca(u,y)] + dis[Lca(x,y)]; printf("%d\n",ans); s.insert(dfn[u]); } else{ if(s.find(dfn[u]) == s.end()){ printf("%d\n",ans); continue; } s.erase(dfn[u]); if(s.size() == 0){ puts("0"); continue; } l = s.lower_bound(dfn[u]); r = s.upper_bound(dfn[u]); if(l == s.begin() || r == s.end()){ l = s.begin();r = s.end();r--; } else l--; x = ddfn[*l];y = ddfn[*r]; ans -= dis[u] - dis[Lca(x,u)] - dis[Lca(u,y)] + dis[Lca(x,y)]; printf("%d\n",ans); } } } int main(){ int T; scanf("%d",&T); int kase = 0; while(T--){ init(); scanf("%d %d",&n,&q); for(int i = 1;i <= n-1;i++){ int u,v,w; scanf("%d %d %d",&u,&v,&w); Add_edge(u,v,w); Add_edge(v,u,w); } Pre(); printf("Case #%d:\n",++kase); solve(); } return 0; }
View Code
相关文章推荐
- 2015区域赛总结
- Android_自定义水波纹菜单弹出效果
- NoClassDefFoundError 集合
- Java锁的种类以及辨析(二):自旋锁的其他种类
- App在iOS9上不能分享至微信,提示微信没有安装
- 井字棋的最优策略竟是先占角!
- 1008. 数组元素循环右移问题 (20)
- 单机运行spark-shell出现ERROR Remoting: Remoting error: [Startup failed]
- Java笔记之数组
- FullPage.js全屏滚动插件学习总结
- 01.MyBatis入门
- Java用ArrayList实现队列
- iOS小技巧-第三方sdk官网汇总(逐步积累)
- ACM 2015 亚洲区域赛北京赛区A题(二分)
- iOS - 常用正则表达式
- saltstack 的web平台集群部署(2)---haproxy的部署
- [POJ 2777] Count Color Splay树
- C++ 标准库类型-String,Vector and Bitset
- Java 计算日期加、减一天
- java锁的种类以及辨析(一):自旋锁