ZOJ 1141 Closest Common Ancestors(LCA)

注意:poj上的数据与zoj不同,第二处输入没有逗号 ' , '

题意:输出测试用例中是最近公共祖先的节点,以及这个节点作为最近公共祖先的次数。

思路:直接求,两个节点一直往上爬,知道爬到同一个节点,这个节点即为最近公共祖先。

这道题的输入挺······,空格可以随意输入。Note that white-spaces (tabs, spaces and line breaks) can be used freely in the input.

5  :  (  3  )

scanf("%d%1s%1s%d%1s",&fa,s1,s2,&m,s3);    //第一处输入,      s1为":"      s2为"("      s3为")"。 

(2,3)
scanf("%1s%d%1s%d%1s",s1,&a,s2,&b,s3);    //第二处输入,       s1为"("      s2为","      s3为")"。 

%1s读取一个字符

 

#include<iostream>
#include<cstring>
#include<stdio.h>
using namespace std;

const int N=1000;
int f[N];//
int sum[N];//记录次数

int depth(int x){//计算层数
	int dep=0;
	while(x!=-1){
		x=f[x];
		dep++;
	}
	return dep;
}
int main(){
	char s1[10],s2[10],s3[10];  
	int n;
	char c;
	while(scanf("%d",&n)!=EOF){//树的节点个数
		memset(f,-1,sizeof(f));
		memset(sum,0,sizeof(sum));
		int tempn=n;
		while(n--){
			int fa,so;
			int m;
			scanf("%d%1s%1s%d%1s",&fa,s1,s2,&m,s3); //注意输入!!!
			while(m--){
				scanf("%d",&so);
				f[so-1]=fa-1;
			}
		}
		int i;
		for(i=0;f[i]>=0;i++);
		int n2;
		scanf("%d",&n2);//要查询的最近公共祖先的节点对数
		while(n2--){
			int a,b;
			scanf("%1s%d%1s%d%1s",s1,&a,s2,&b,s3);//注意输入!!!
			a--;b--;
			int depa=depth(a);
			int depb=depth(b);
			while(a!=b){
				if(depa>depb)a=f[a],depa--;
				else b=f[b],depb--;
			}
			sum[a]++;
		}
		for(i=0;i<tempn;i++){
			if(sum[i]>0)
				printf("%d:%d\n",i+1,sum[i]);
		}
	}
	return 0;
}


 

posted @ 2014-09-27 16:19  gongpixin  阅读(174)  评论(0编辑  收藏  举报