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 ?


 
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)




 
Output
Each testcase outputs a line of "Case #x:" , x starts from 1.

The next q line represents the answer to each operation.


 
Sample Input
1
6 5
1 2 2
1 5 2
5 6 2
2 4 2
2 3 2
1 5
1 3
1 4
1 2
2 5
 
Sample Output
Case #1:
0
6
8
8
4
 
Author
FZUACM
 
Source
 

/* ***********************************************
Author :CKboss
Created 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 mid
if(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 solve
int solve(int kind,int x)
{
Node ND = (Node){x,ti[x]}; /// if in mid find nearst point
set<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;
}

HDOJ 5296 Annoying problem LCA+数据结构的更多相关文章

  1. HDU 5296 Annoying problem LCA+树状数组

    题解链接 Annoying problem Time Limit: 16000/8000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/O ...

  2. HDU 5296 Annoying problem (LCA,变形)

    题意: 给一棵n个节点的树,再给q个操作,初始集合S为空,每个操作要在一个集合S中删除或增加某些点,输出每次操作后:要使得集合中任意两点互可达所耗最小需要多少权值.(记住只能利用原来给的树边.给的树边 ...

  3. HDU 5296 Annoying problem dfs序 lca

    Annoying problem 题目连接: http://acm.hdu.edu.cn/showproblem.php?pid=5296 Description Coco has a tree, w ...

  4. HDU 5296 Annoying problem dfs序 lca set

    Annoying problem Problem Description Coco has a tree, whose nodes are conveniently labeled by 1,2,…, ...

  5. HDU 5296 Annoying problem

    Annoying problem Time Limit: 16000/8000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others ...

  6. hdu5296(2015多校1)--Annoying problem(lca+一个公式)

    Annoying problem Time Limit: 16000/8000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others ...

  7. 2015 Multi-University Training Contest 1 hdu 5296 Annoying problem

    Annoying problem Time Limit: 16000/8000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others ...

  8. 【HDOJ】5296 Annoying problem

    LCA+RMQ.挺不错的一道题目. 思路是如何通过LCA维护费用.当加入新的点u是,费用增量为dis[u]-dis[lca(u, lower_u)] - dis[lca(u, greater_u)] ...

  9. HDU5296 Annoying problem(LCA)

    //#pragma comment(linker, "/STACK:1677721600") #include <map> #include <set> # ...

随机推荐

  1. POI实现Excel2003插入多张图片

    POI的操作Excel时,不可避免有操作图片的处理.怎么插入图片呢?网上也有不少介绍. 下面的代码是向Excel中插入多张图片的例子: public static void main(String[] ...

  2. 【codeforces 794A】Bank Robbery

    [题目链接]:http://codeforces.com/contest/794/problem/A [题意] 每个位置上可能有物品(>=1)或是没物品 你一开始在某一个位置b; 然后你最左可以 ...

  3. fensorflow 安装报错 DEPENDENCY ERROR

    1.错误信息 DEPENDENCY ERROR The target you are trying to run requires an OpenSSL implementation. Your sy ...

  4. IntelliJ IDEA 初始化项目时No Java SDK Found

    IntelliJ IDEA 初始化项目时No Java SDK Found 自己在Project SDK后面的New按钮进行JDK的添加:

  5. 排序(3)---------冒泡排序(C语言实现)

    说到冒泡排序,大一的时候第一次学习这个排序算法,可能大家不知道,"冒泡"在我说的方言里面是吹牛逼的意思. 所以就认为这个排序算法特吹牛逼有木有. 相信大家对全部的排序算法,这个想必 ...

  6. C++11新特性应用--介绍几个新增的便利算法(用于分区的几个算法)

    今天继续. C++11新增的关于Non-modifying sequence operations和Modifying sequence operations的算法已经写了.具体信息见之前的博客. 以 ...

  7. 怎样用批处理来执行多个exe文件

    怎样用批处理来运行多个exe文件 @echo off start *****.exe start *****.exe start *****.exe start *****.exe 接着我们就能够运行 ...

  8. Found conflicts between different versions of the same dependent assembly that could not be resolved

    https://stackoverflow.com/questions/24772053/found-conflicts-between-different-versions-of-the-same- ...

  9. iOS学习必须了解的七大手势

    文章只要你有一点点基础应该就可以看的懂,文章只为学习交流 #import "ViewController.h" @interface ViewController () @prop ...

  10. mysql 字符串的处理

    1.SUBSTRING 2.SUBSTRING_INDEX 3. right/left 4.POSITION sql实例 select left(right(SUBSTRING_INDEX(data_ ...