• POJ 1470/PKU 1470 Closest Common Ancestors __LCA


    题目链接:http://poj.org/problem?id=1470


    题目大意:开始让你构造一棵树,然后有Q对u,v,最后让你求出每对u,v的最近祖先的编号和次数。

    输入一个Q,然后有Q组(u,v)每组中间还有空格,tab等。但,稍稍想一下就能发现,Q组uv一共有Q*2个字符串,所以我们讲稿Q*2组str就可以了scanf("%s",str),然后处理每组str求得u,v

    /*/
    /*lca离线算法
    /*/
    
    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    #include<queue>
    #include<ctime>
    #include<cmath>
    #include<climits>
    #define sf scanf
    #define pf printf
    #define cls(a) memset(a,0,sizeof(a))
    #define _cls(a) memset(a,-1,sizeof(a))
    
    
    using namespace std;
    
    struct Edge_t{
    	int to,next;
    }edge[3010];
    int head[1010],et,qhead[1010],qt;//- -
    int root[1010],ind[1010];//union & indgree
    int anst[1010],color[1010];//ansector & color(visit)
    //int res[400010];//respond
    int num[1010];
    vector<int>query[1010];
    
    inline void adde(int u,int v){//add edge
    	edge[et].to=v,edge[et].next=head[u],head[u]=et++;
    }
    inline int Find(int x){ return root[x]=root[x]==x?x:Find(root[x]);}
    
    void Union(int u,int v){
    	int ra=Find(u),rb=Find(v);
    	root[rb]=ra;
    }
    
    void LCA(int u){//从根节点开始
    	int v,e;
    	anst[u]=u;
    	for(e=head[u];e!=-1;e=edge[e].next){
    		LCA((v=edge[e].to));
    		Union(u,v);
    		anst[Find(u)]=u;
    	}
    	color[u]=1;
    	int s=query[u].size(),i=0;
    	for(;i<s;++i)
    		if(color[v=query[u][i]]){
    			//res[query[e].pos]=
    			num[anst[Find(v)]]++;
    		}
    }
    
    int deal(char *s,int v){
    	int i,ret=0;
    	if(v){
    		for(i=1;s[i];++i)
    			ret*=10,ret+=s[i]-'0';
    	}else{
    		for(i=0;s[i+1];++i)
    			ret*=10,ret+=s[i]-'0';
    	}
    	//pf("ret=%d\n",ret);
    	return ret;
    }
    
    int main(){
    	int n,m,i;
    	int t,u,v;
    	while(~sf("%d",&n)){
    		for(qt=et=0,i=1;i<=n;++i)
    			root[i]=i,head[i]=-1,ind[i]=0,anst[i]=-1,color[i]=0,query[i].clear(),num[i]=0;
    		for(i=0;i<n;++i){
    			sf("%d:(%d)",&u,&v);
    			//pf("u=%d v=%d\n",u,v);
    			while(v--){
    				sf("%d",&m);
    				adde(u,m);
    				ind[m]++;
    			}
    		}
    		int Q;
    		char str[20];
    		sf("%d",&Q);
    		Q<<=1;//一共Q*2个字符串
    		for(i=0;i<Q;++i){
    			sf("%s",str);
    			if(i&1) v=deal(str,0),query[u].push_back(v),query[v].push_back(u);
    			else u=deal(str,1);//后面那个1表示u,0表示v
    		}
    		for(i=1;i<=n;++i)
    			if(!ind[i]) break;
    		LCA(i);
    		for(i=1;i<=n;++i)
    			if(num[i]) pf("%d:%d\n",i,num[i]);
    	}
    	return 0;
    }
    


  • 相关阅读:
    进程、线程、处理器间的关系研究(未完待续)
    Java运行原理研究(未完待续)
    libuv的多线程之间传递消息
    C++对象与其第一个非静态成员地址相同
    libuv移植到android
    pthread在Qt+Windows下的使用
    libuv在mingw下编译
    libxml2在mingw下编译
    libcurl在mingw下编译
    string的内存本质
  • 原文地址:https://www.cnblogs.com/dyllove98/p/3138769.html
Copyright © 2020-2023  润新知