zoukankan      html  css  js  c++  java
  • SPOJ Query on a tree V

    You are given a tree (an acyclic undirected connected graph) with N nodes. The tree nodes are numbered from 1 to N. We define dist(a, b) as the number of edges on the path from node a to node b.

    Each node has a color, white or black. All the nodes are black initially.

    we will ask you to perfrom some instructions of the following form:

    0 i : change the color of i-th node(from black to white, or from white to black).
    1 v : ask for the minimum dist(u, v), node u must be white(u can be equal to v). Obviously, as long as node v is white, the result will always be 0.

    Input

    In the first line there is an integer N (N <= 100000)
    In the next N-1 lines, the i-th line describes the i-th edge: a line with two integers a b denotes an edge between a and b.
    In the next line, there is an integer Q denotes the number of instructions (Q <= 100000)
    In the next Q lines, each line contains an instruction "0 i" or "1 v"

    Output

    For each "1 v" operation, print one integer representing its result. If there is no white node in the tree, you should write "-1".
    Example

    解题报告:
    写了这个题之后算是对点分治有了个新认识,感觉以前写的都是假的啊.
    突然发现任意两个点之间的路径仿佛都只会交在一个重心上,这样我们就很好弄了,对每一个重心维护一个小根堆,如果0操作弄出一个白点,我们就把这个白点加入到包含它的重心所在的堆里面,然后询问就直接查询包含该点的重心,用(disi,v+q[i].top())去更新答案,i为某重心,q为该重心的堆,复杂度(O(nlog2n))

    #include <algorithm>
    #include <iostream>
    #include <cstdlib>
    #include <cstring>
    #include <cstdio>
    #include <queue>
    #include <vector>
    #include <cmath>
    #define RG register
    #define il inline
    #define iter iterator
    #define Max(a,b) ((a)>(b)?(a):(b))
    #define Min(a,b) ((a)<(b)?(a):(b))
    using namespace std;
    const int N=100005,inf=2e8;
    int gi(){
    	int str=0;char ch=getchar();
    	while(ch>'9' || ch<'0')ch=getchar();
    	while(ch>='0' && ch<='9')str=(str<<1)+(str<<3)+ch-48,ch=getchar();
    	return str;
    }
    int n,num=0,head[N],to[N<<1],nxt[N<<1],root=0,f[N]={inf},son[N],sum;
    bool vis[N];
    struct node{
    	int x,id;
    	bool operator <(const node &pp)const{
    		return x>pp.x;
    	}
    };
    priority_queue<node>q[N];
    void link(int x,int y){
    	nxt[++num]=head[x];to[num]=y;head[x]=num;
    }
    int Head[N],NUM=0,To[N*30],Dis[N*30],Next[N*30];
    void add(int x,int y,int z){
    	Next[++NUM]=Head[x];To[NUM]=y;Dis[NUM]=z;Head[x]=NUM;
    }
    bool col[N];
    void getdis(int x,int last,int dist){
    	add(x,root,dist);
    	int u;
    	for(int i=head[x];i;i=nxt[i]){
    		u=to[i];if(u==last || vis[u])continue;
    		getdis(u,x,dist+1);
    	}
    }
    void getroot(int x,int last){
    	int u;son[x]=1;f[x]=0;
    	for(int i=head[x];i;i=nxt[i]){
    		u=to[i];if(vis[u] || u==last)continue;
    		getroot(u,x);
    		son[x]+=son[u];
    		f[x]=Max(f[x],son[u]);
    	}
    	f[x]=Max(f[x],sum-son[x]);
    	if(f[x]<f[root])root=x;
    }
    void dfs(int x){
    	int u;vis[x]=true;
    	getdis(x,x,0);
    	for(int i=head[x];i;i=nxt[i]){
    		u=to[i];if(vis[u])continue;
    		root=0;sum=son[u];getroot(u,x);
    		dfs(root);
    	}
    }
    void updata(int x){
    	col[x]^=1;
    	if(col[x])
    		for(int i=Head[x];i;i=Next[i])
    			q[To[i]].push((node){Dis[i],x});
    }
    int query(int x){
    	if(col[x])return 0;
    	int ret=inf;
    	for(int i=Head[x];i;i=Next[i]){
    		int u=To[i];
    		while(!q[u].empty() && !col[q[u].top().id])q[u].pop();
    		if(!q[u].empty())ret=Min(ret,q[u].top().x+Dis[i]);
    	}
    	return ret==inf?-1:ret;
    }
    void work()
    {
    	int x,y;
    	n=gi();
    	for(int i=1;i<n;i++){
    		x=gi();y=gi();
    		link(x,y);link(y,x);
    	}
    	sum=n;root=0;getroot(1,1);
    	dfs(root);
    	int Q=gi(),flag;
    	while(Q--){
    		flag=gi();x=gi();
    		if(!flag)updata(x);
    		else printf("%d
    ",query(x));
    	}
    }
    
    int main()
    {
    	work();
    	return 0;
    }
    
    
  • 相关阅读:
    从未改过的网名,一如既往的孤荷凌寒——我的信息技术之路之五
    编程思维的养成——我的信息技术之路之五
    从无知无畏到虚心借鉴——我的信息技术之路之四
    相信自己,看着目标前进——我的信息技术之路之三
    先迈开步子再找路——我的信息技术之路之二
    每个问题的解决都预设多种算法方案——我的信息技术之路之七
    软件开发流程之三:可行性研究
    软件开发流程之二:开发流程
    软件开发流程之九:项目组建设
    软件开发流程之七:软件测试
  • 原文地址:https://www.cnblogs.com/Yuzao/p/7450526.html
Copyright © 2011-2022 走看看