题目链接:http://poj.org/problem?id=1470
题意:LCA
方法:Tarjin 或 RMQ
裸题,不解释,就是输入有点麻烦。。。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<vector>
using namespace std;
#define clr(arr,v) memset(arr,v,sizeof(arr))
const int M = 1005;
int h[M],num[M],nex[M],pos;
bool flag[M],degree[M];
int cnt[M],father[M],ancestor[M];
vector<int> Q[M];
void init()
{
pos = 0;
for(int i = 0;i < M;++i)
{
Q[i].clear();
cnt[i] = 0;
h[i] = -1;
degree[i] = false;
flag[i] = false;
}
}
void add(int u,int v)
{
num[pos] = v;
nex[pos] = h[u];
h[u] = pos++;
}
void make_set(int u)
{
father[u] = u;
ancestor[u] = u;
}
int find(int u)
{
return father[u] == u?u:father[u] = find(father[u]);
}
void Union(int u,int v)
{
father[find(u)] = find(v);
}
void tarjin_lca(int u)
{
make_set(u);
for(int i = h[u];i != -1;i = nex[i])
{
tarjin_lca(num[i]);
Union(u,num[i]);
ancestor[find(u)] = u;
}
flag[u] = true;
for(int i = 0;i < Q[u].size();++i)
{
int cur = Q[u][i];
if(flag[cur]) cnt[ ancestor[find(cur)] ]++;
}
}
int main()
{
char ch;
int n,m;
while(scanf("%d",&n) != EOF)
{
init();
int u,s,v;
for(int i = 1;i <= n;++i)
{
scanf("%d",&u);
while((ch = getchar()) && ch != '(');
scanf("%d",&s);
while((ch = getchar()) && ch != ')');
for(int j = 0;j < s;++j)
{
scanf("%d",&v);
add(u,v);
degree[v] = true;
}
}
scanf("%d",&m);
for(int i = 0;i < m;++i)
{
while((ch = getchar()) && ch != '(');
scanf("%d%d",&u,&v);
Q[u].push_back(v);
Q[v].push_back(u);
while((ch = getchar()) && ch != ')');
}
for(int i = 1;i <= n;++i)
{
if(!degree[i]) tarjin_lca(i);
}
for(int i = 1;i <= n;++i)
{
if(cnt[i] != 0)
{
printf("%d:%d\n",i,cnt[i]);
}
}
}
return 0;
}