HDOJ 5296 Annoying problem LCA+数据结构
来源:互联网 发布:小米手机全系列 知乎 编辑:程序博客网 时间:2024/04/28 03:18
dfs一遍得到每个节点的dfs序,对于要插入的节点x分两种情况考虑:
1,如果x可以在集合中的某些点之间,找到左边和右边距离x最近的两个点,即DFS序小于x的DFS序最大点,和大于x的DFS序最小的点......
2.如果x在集合中的点某一侧,则找距离x的dfs序最小和最大的点
将x插入这个集合最少要走的距离为 dist[x]-dist[LCA(left,x)]-dist[LCA(right,x)]+dist[LCA(left,right)]
删除同理
Annoying problem
Time Limit: 16000/8000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)Total Submission(s): 334 Accepted Submission(s): 95
Problem Description
Coco has a tree, whose nodes are conveniently labeled by 1,2,…,n, which has n-1 edge,each edge has a weight. An existing set S is initially empty.
Now there are two kinds of operation:
1 x: If the node x is not in the set S, add node x to the set S
2 x: If the node x is in the set S,delete node x from the set S
Now there is a annoying problem: In order to select a set of edges from tree after each operation which makes any two nodes in set S connected. What is the minimum of the sum of the selected edges’ weight ?
Now there are two kinds of operation:
1 x: If the node x is not in the set S, add node x to the set S
2 x: If the node x is in the set S,delete node x from the set S
Now there is a annoying problem: In order to select a set of edges from tree after each operation which makes any two nodes in set S connected. What is the minimum of the sum of the selected edges’ weight ?
Input
one integer number T is described in the first line represents the group number of testcases.( T<=10 )
For each test:
The first line has 2 integer number n,q(0<n,q<=100000) describe the number of nodes and the number of operations.
The following n-1 lines each line has 3 integer number u,v,w describe that between node u and node v has an edge weight w.(1<=u,v<=n,1<=w<=100)
The following q lines each line has 2 integer number x,y describe one operation.(x=1 or 2,1<=y<=n)
For each test:
The first line has 2 integer number n,q(0<n,q<=100000) describe the number of nodes and the number of operations.
The following n-1 lines each line has 3 integer number u,v,w describe that between node u and node v has an edge weight w.(1<=u,v<=n,1<=w<=100)
The following q lines each line has 2 integer number x,y describe one operation.(x=1 or 2,1<=y<=n)
Output
Each testcase outputs a line of "Case #x:" , x starts from 1.
The next q line represents the answer to each operation.
The next q line represents the answer to each operation.
Sample Input
16 51 2 21 5 25 6 22 4 22 3 21 51 31 41 22 5
Sample Output
Case #1:06884
Author
FZUACM
Source
2015 Multi-University Training Contest 1
/* ***********************************************Author :CKbossCreated Time :2015年07月21日 星期二 21时06分11秒File Name :HDOJ5296.cpp************************************************ */#include <iostream>#include <cstdio>#include <cstring>#include <algorithm>#include <string>#include <cmath>#include <cstdlib>#include <vector>#include <queue>#include <set>#include <map>using namespace std;typedef long long int LL;const int maxn=120100;const int INF=0x3f3f3f3f;struct Edge{int to,next,cost;}edge[maxn*2];int Adj[maxn],Size;void init() { memset(Adj,-1,sizeof(Adj)); Size=0; }void Add_Edge(int u,int v,int c){edge[Size].to=v; edge[Size].cost=c;edge[Size].next=Adj[u];Adj[u]=Size++;}int n,q;int dist[maxn],ti[maxn],cnt;void dfs(int len,int u,int fa){dist[u]=len; ti[u]=cnt;for(int i=Adj[u];~i;i=edge[i].next){int to=edge[i].to;int cost=edge[i].cost;if(to==fa) continue;cnt++;dfs(len+cost,to,u);}}/********************** LCA **********************************/const int DEG=20;int fa[maxn][DEG];int deg[maxn];void BFS(int root){queue<int> q;memset(deg,0,sizeof(deg));memset(fa,0,sizeof(fa));deg[root]=0;fa[root][0]=root;q.push(root);while(!q.empty()){int u=q.front(); q.pop();for(int i=1;i<DEG;i++){fa[u][i]=fa[fa[u][i-1]][i-1];}for(int i=Adj[u];~i;i=edge[i].next){int v=edge[i].to;if(v==fa[u][0]) continue;deg[v]=deg[u]+1;fa[v][0]=u;q.push(v);}}}int LCA(int u,int v){if(deg[u]>deg[v]) swap(u,v);int hu=deg[u],hv=deg[v];int tu=u,tv=v;for(int det=hv-hu,i=0;det;i++,det=det/2){if(det&1) tv=fa[tv][i];}if(tu==tv) return tu;for(int i=DEG-1;i>=0;i--){if(fa[tu][i]==fa[tv][i]) continue;tu=fa[tu][i]; tv=fa[tv][i];}return fa[tu][0];}struct Node{int val,cnt;bool operator<(const Node& nd) const { return cnt<nd.cnt; }bool operator==(const Node& nd) const { return val==nd.val; }bool operator!=(const Node& nd) const { return val!=nd.val; }};set<Node> st;int CL(int flag,Node ND){if(flag==0) st.erase(ND);set<Node>::iterator it1,it2;int x=ND.val;it2=st.upper_bound(ND);it1=it2; it1--;/// check if in midif(it1->val!=0&&it2->val!=n+10) /// in mid{int left=it1->val;int right=it2->val;if(flag) st.insert(ND);return dist[x]-dist[LCA(x,left)]-dist[LCA(x,right)]+dist[LCA(left,right)];}else // in side{if(it2->val==n+10) /// all in left{it2=st.begin(); it2++;int left=it2->val;int right=it1->val;if(flag) st.insert(ND);return dist[x]-dist[LCA(x,left)]-dist[LCA(x,right)]+dist[LCA(left,right)];}else if(it1->val==0) /// all in right{int left=it2->val;it1=st.end();it1--; it1--;int right=it1->val;if(flag) st.insert(ND);return dist[x]-dist[LCA(x,left)]-dist[LCA(x,right)]+dist[LCA(left,right)];}}}/// return change val of solveint solve(int kind,int x){Node ND = (Node){x,ti[x]};/// if in mid find nearst pointset<Node>::iterator it1,it2;if(kind==1) // add{if(st.count(ND)==1) return 0;if(st.size()==2){st.insert(ND);return 0;}else if(st.size()==3){it1=st.begin(); it1++;int v=it1->val;st.insert(ND);return dist[x]+dist[v]-2*dist[LCA(v,x)];}else{return CL(1,ND);}}else if(kind==2) // remove{if(st.count(ND)==0) return 0;if(st.size()==3){st.erase(ND);return 0;}else if(st.size()==4){it1=st.begin();it1++;int v=it1->val; it1++;int u=it1->val;st.erase(ND);return dist[u]+dist[v]-2*dist[LCA(u,v)];}else{return CL(0,ND);}}}int main(){ //freopen("in.txt","r",stdin); //freopen("out.txt","w",stdout);int T_T,cas=1;scanf("%d",&T_T);while(T_T--){scanf("%d%d",&n,&q);init();for(int i=0,u,v,c;i<n-1;i++){scanf("%d%d%d",&u,&v,&c);Add_Edge(u,v,c); Add_Edge(v,u,c);}cnt=1; st.clear();st.insert((Node){0,-INF});st.insert((Node){n+10,INF});dfs(0,1,1); BFS(1);int all=0;printf("Case #%d:\n",cas++);while(q--){int k,x;scanf("%d%d",&k,&x);if(k==1) all+=solve(k,x);else if(k==2) all-=solve(k,x);printf("%d\n",all);}} return 0;}
1 0
- HDOJ 5296 Annoying problem LCA+数据结构
- HDOJ 5296 Annoying problem
- hdu 5296 Annoying problem(LCA)
- 【LCA】HDU 5296 Annoying problem
- hdu 5296 Annoying problem (LCA)
- HDU 5296 Annoying problem LCA+树状数组
- HDU 5296 Annoying problem dfs序+lca
- hdu5296 Annoying problem (LCA+SET)
- HDU 5296 Annoying Problem 树链剖分 LCA 倍增法
- HDU 5296 Annoying problem(点到树链的距离+LCA)
- [HDU 5296] Annoying problem (DFS序性质+LCA)
- 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(2015 Multi-University Training Contest 1 )LCA
- Caffe 深度学习框架上手教程
- Array的常用操作
- android像素db转px或者px转dp(有案例)
- 【计蒜客系列】挑战难题20:跳跃游戏二
- 菜鸟系列——最短路
- HDOJ 5296 Annoying problem LCA+数据结构
- IBM DB210.1 Linux安装
- iOS隐藏桌面图标
- 10种软件滤波算法
- SylixOS xinput 系统
- 在ubuntu下无法进入windows盘
- spring的beanFactory和factoryBean
- 微信蓝牙外设协议 1
- Poco for Windows 编译 x86 x64