HDU6203 ping ping ping 【LCA+BIT】
来源:互联网 发布:淘宝怎么做手机上 编辑:程序博客网 时间:2024/05/21 09:59
传送门
先求dfs序in[]和out[],以及lca
将不能连通的(u,v)按lca深度从大到小排序
树状数组维护数组flag[]
依次处理每对(u,v)
#include<stdio.h>#include<bits/stdc++.h>#define ll long long#define pii pair<int,int>#define pll pair<ll,ll>#define MEM(a,x) memset(a,x,sizeof(a))#define lowbit(x) ((x)&-(x))using namespace std;const int inf=1e9+7;const int INF = inf;const int N = 1e4 + 5;//顶点数const int M = 50000 + 5;//查询数struct Query{ int u,v,lca;};vector<int>G[N];//fist:to second:w边权vector<pii>queryTo[N];//first:to second:这个查询在query[M]中的下标Query query[M];int par[N];//并查集bool visited[N];//Tarjan标记是否被访问过inline int find(int x){ return x==par[x]?x:par[x]=find(par[x]);}void Tarjan(int u){ visited[u]=true; for(int i=0;i<G[u].size();++i){ int to=G[u][i]; if(visited[to]==false){ Tarjan(to); par[to]=u; } } for(int i=0;i<queryTo[u].size();++i){ int v=queryTo[u][i].first; int index=queryTo[u][i].second; if(visited[v]) query[index].lca=find(v); }}void init(int n){ fill(visited,visited+n+1,0); for(int i=0;i<=n;++i){ par[i]=i; }}int in[N],out[N],depth[N];void dfs(int u,int &t,int fa,int d){ in[u]=++t; depth[u]=d; for(int v:G[u]){ if(v!=fa){ dfs(v,t,u,d+1); } } out[u]=t;}struct Bit{ int c[N],n; void init(int n){ this->n=n+1; fill(c,c+n+2,0); } void add(int x,int val){//a[x]...a[n] 全部+val x+=1; while(x<=n){ c[x]+=val; x+=lowbit(x); } } ll sum(int x){//a[x] ll ans=0; x+=1; while(x){ ans+=c[x]; x-=lowbit(x); } return ans; }}bit;bool operator>(const Query&a,const Query&b){ return depth[a.lca]>depth[b.lca];}int slove(int n,int q){ init(n); { int t=-1; dfs(0,t,-1,0); } bit.init(n); Tarjan(0); sort(query,query+q,greater<Query>()); int ans=0; for(int i=0;i<q;++i){ Query&t=query[i]; if(bit.sum(in[t.u])||bit.sum(in[t.v])){ continue; } ++ans; int st=in[t.lca],ed=out[t.lca]; bit.add(st,1); bit.add(ed+1,-1); } return ans;}int main(){ //freopen("/home/lu/code/r.txt","r",stdin); //freopen("/home/lu/code/w.txt","w",stdout); int n; while(~scanf("%d",&n)){ for(int i=0;i<=n;++i){ G[i].clear(); queryTo[i].clear(); } for(int i=1;i<=n;++i){ int u,v; scanf("%d%d",&u,&v); G[u].push_back(v); G[v].push_back(u); } int p; scanf("%d",&p); for(int i=0;i<p;++i){ int u,v; scanf("%d%d",&u,&v); query[i]={u,v,-1}; queryTo[u].push_back({v,i}); queryTo[v].push_back({u,i}); } printf("%d\n",slove(n,p)); } return 0;}
阅读全文
0 0
- HDU6203 ping ping ping 【LCA+BIT】
- HDU 6203ping ping ping(LCA+贪心)
- ping .............
- ping
- ping
- ping
- ping
- ping
- Ping
- ping
- ping
- ping
- ping
- ping .
- ping
- ping
- ping
- ping ....
- mySQL之索引
- C学习心得二(printf用法)
- 神经网络初探:反向传播公式的简易证明
- JS最全的图片预加载技术并且封装成插件
- <Android 基础(四十二)> MultiDex
- HDU6203 ping ping ping 【LCA+BIT】
- hadoop和spark的异同
- iOS 仿 UC 浏览器个人中心 (下拉实现果冻效果)
- 通过 “期望”实现的一个并发快排
- C语言 typeof关键字
- hdu 4034 【floyed变形】
- Jquery中使用$append出现添加两次及Jquery对象多次使用的方法
- Android 高德地图的定位功能,以及动态开启权限
- 快速排序