poj 1470 Closest Common Ancestors

由于这个题很蛋疼 会有很详细的注释

#pragma comment (linker, "/STACK:1024000000, 1024000000")
#include <vector>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>

using namespace std;

const int N = 1010;
const int MAX = 1000010;

int n,m;
bool root[N];
int query[N][N];
int tot, head[N];
int father[N],ans[MAX],vis[N],cnt[N];


struct edge{
	int v, next;
}node[MAX];

void init(){
	tot = 0;
	memset(cnt, 0, sizeof(cnt));
	memset(vis, -1, sizeof(vis));
	memset(root, true, sizeof(root));
	memset(head, -1, sizeof(head));
	memset(query, 0, sizeof(query));//就是因为这个没有初始化 output exceeded= =。郁闷死!
}

void addedge(int u, int v){//链式前向星
	node[tot].v = v;
	node[tot].next = head[u];
	head[u] = tot++;
}

int find(int x){
	if(x != father[x])
		father[x] = find(father[x]);
	return father[x];
}

void lca(int u, int fa){
	father[u] = u;
	for(int i=head[u]; i!=-1; i=node[i].next){
		int v = node[i].v;
		if(vis[v] != -1) continue;
		lca(v, fa);
		father[v] = u;
	}
	vis[u] = fa;//由于是单向边 放在中间不会导致死循化,重复统计lca访问次数
	for(int i=1; i<=n; i++)
		if(vis[i] == fa && query[u][i])
			cnt[find(i)] += query[u][i];
}

int main(){
//          freopen("in.txt", "r", stdin);
	while(scanf("%d",&n) == 1){
		init();
		for(int i=0; i<n; i++){
			int u, num;
			scanf("%d:(%d)", &u,&num);
			for(int i=0; i<num; i++){
				int v;
				scanf("%d",&v);
				root[v] = false;
				addedge(u, v);//有向边
			}
		}
		scanf("%d",&m);
		for(int i=0; i<m; i++){
			int u, v;
                        scanf(" (%d %d) ",&u,&v);
			query[u][v]++;//用矩阵存储是因为存在重复的询问且统计的是lca的访问次数
			query[v][u]++;
			ans[i] = -1;
		}
		int i;
		for(i=1; i<=n; i++)
			if(root[i]) break;
		lca(i, i);//如果求解的是lca本身 必须从根开始搜索 但是如果是求距离就不需要
		for(int i=1; i<=n; i++)
			if(cnt[i]) printf("%d:%d\n",i,cnt[i]);
	}
	return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值