Acdream 1424 树链剖分
来源:互联网 发布:维棠mac版 编辑:程序博客网 时间:2024/05/09 10:50
还是做的少,都完全不知道往树链剖分方向想,赛后听了昂神思路才恍然。
首先,石头路连接构成的是一棵树,然后,对于泥路,可以看作是在它的期末位置所在链上覆盖,被覆盖到两次的石头路都是破坏后不能达到效果的,而对于只被覆盖过1次的石头路则是可以的,这条路被断后,剩下一个要断的土路即为覆盖它的那条。所以,只要树链剖分一下,记录被覆盖次数,然后找出只被覆盖了一次的个数即为答案。
#include<iostream>#include<cstdio>#include<cstring>#include<vector>#include<queue>using namespace std;struct node{ int l,r,a;}t[88888];vector<int>g[22222];int f[22222],top[22222],w[22222],s[22222];int dep[22222],son[22222];int m,n,sz;int qx[222222],qy[222222],qnum;void dfs1(int u){ s[u]=1; son[u]=0; for(int i=0;i<g[u].size();i++) { int v=g[u][i]; if(v==f[u])continue; dep[v]=dep[u]+1; f[v]=u; dfs1(v); s[u]+=s[v]; if(!son[u]||s[v]>s[son[u]])son[u]=v; }}void dfs2(int u,int ff){ top[u]=ff; w[u]=++sz; if(son[u])dfs2(son[u],ff); for(int i=0;i<g[u].size();i++) { int v=g[u][i]; if(v==f[u]||v==son[u])continue; dfs2(v,v); }}void build(int ll,int rr,int rot){ t[rot].l=ll; t[rot].r=rr; t[rot].a=0; if(ll==rr)return; int mid=(ll+rr)/2; build(ll,mid,rot<<1); build(mid+1,rr,rot<<1|1);}void update(int ll,int rr,int rot){ if(ll>rr)return; if(t[rot].l==ll&&t[rot].r==rr) { t[rot].a++; return; } if(t[rot].a) { t[rot<<1].a+=t[rot].a; t[rot<<1|1].a+=t[rot].a; t[rot].a=0; } int mid=(t[rot].l+t[rot].r)/2; if(rr<=mid)update(ll,rr,rot<<1); else if(ll>mid)update(ll,rr,rot<<1|1); else { update(ll,mid,rot<<1); update(mid+1,rr,rot<<1|1); }}void solve(int u,int v){ int uu=top[u]; int vv=top[v]; while(uu!=vv) { if(dep[u]>dep[v]) { swap(u,v); swap(uu,vv); } update(w[vv],w[v],1); v=f[vv]; vv=top[v]; } if(dep[u]>dep[v])swap(u,v); update(w[son[u]],w[v],1);}int query(int rot){ if(t[rot].l==t[rot].r) { if(t[rot].a==1)return 1; else return 0; } if(t[rot].a) { t[rot<<1].a+=t[rot].a; t[rot<<1|1].a+=t[rot].a; t[rot].a=0; } return query(rot<<1)+query(rot<<1|1);}int main(){ int u,v,c; scanf("%d%d",&n,&m); sz=0; qnum=0; for(int i=0;i<m;i++) { scanf("%d%d%d",&u,&v,&c); if(c==0) { qx[qnum]=u; qy[qnum]=v; qnum++; } else { g[u].push_back(v); g[v].push_back(u); } } dep[1]=0; f[1]=1; dfs1(1); dfs2(1,1); build(1,sz,1); for(int i=0;i<qnum;i++)solve(qx[i],qy[i]); printf("%d\n",query(1)); return 0;}
0 0
- Acdream 1424 树链剖分
- Acdream 1424 Diversion 树链剖分+线段树
- 树链剖分 ACDream 1133 LCA
- ACdream
- Acdream
- ACdream
- ACdream
- ACdream
- ACdream
- ACdream
- ACdream
- ACdream
- ACdream
- ACdream
- ACdream
- ACdream
- ACdream 1424 Diversion(树链剖分+线段树)
- 【ACdream】1103 瑶瑶正式成为CEO 树链剖分+费用流
- GDB调试程序 基础篇
- linkin大话设计模式--桥接模式
- FPGA 使用verilog 编写的AD tlc549 测试程序,数码管做显示,本程序已验证
- oozie 工作流调度引擎总结
- 九度OJ1451-不容易系列之一
- Acdream 1424 树链剖分
- mysql 索引注意事项:聚合函数COUNT
- 游戏框架其八:2D图像 { Sprite | Font }
- ACdream 1427 Nice Sequence
- 重建二叉树
- 程序猿才懂得幽默~~
- 写作是越写越好,越不写越不好
- 软考——宏观概览
- sublime常用配置