Time Limit: 2000MS | Memory Limit: 10000K | |
Total Submissions: 7027 | Accepted: 2199 |
Description
Input
nr_of_vertices
vertex:(nr_of_successors) successor1 successor2 ... successorn
...
where vertices are represented as integers from 1 to n ( n <= 900 ). The tree description is followed by a list of pairs of vertices, in the form:
nr_of_pairs
(u v) (x y) ...
The input file contents several data sets (at least one).
Note that white-spaces (tabs, spaces and line breaks) can be used freely in the input.
Output
For example, for the following tree:

Sample Input
5 5:(3) 1 4 2 1:(0) 4:(0) 2:(1) 3 3:(0) 6 (1 5) (1 4) (4 2) (2 3) (1 3) (4 3)
Sample Output
2:1 5:5
Hint
Source
#include<stdio.h>
#include<vector>
using namespace std;
const int MAX=901;
int f[MAX];
int r[MAX];
int indegree[MAX];//保存每个节点的入度
int visit[MAX];
vector<int> tree[MAX],Qes[MAX];
int ancestor[MAX];
int sum[MAX];
void init(int n)
{
for(int i=1;i<=n;i++)
{
r[i]=1;//类似于rank数组
f[i]=i;//用于并查集记录父亲节点
indegree[i]=0;//节点的层号
visit[i]=0;//是否被访问
ancestor[i]=0;//祖先
tree[i].clear();//清空
Qes[i].clear();
sum[i]=0;
}
}
int find(int n)
{ //查找函数,并压缩路径
if(f[n]==n) return n;
else f[n]=find(f[n]);
return f[n];
}
int Union(int x,int y)
{ //合并函数,如果属于同一分支则返回0,成功合并返回1
int a=find(x);
int b=find(y);
if(a==b) return 0;
//相等的话,x向y合并
else if(r[a]<=r[b])
{
f[a]=b;
r[b]+=r[a];
}
else
{
f[b]=a;
r[a]+=r[b];
}
return 1;
}
void LCA(int u)
{
ancestor[u]=u;
int size=tree[u].size();
for(int i=0;i<size;i++)
{
LCA(tree[u][i]);
Union(u,tree[u][i]);
ancestor[find(u)]=u;
}
visit[u]=1;
size=Qes[u].size();
for(int i=0;i<size;i++)
{ //如果已经访问了问题节点,就可以返回结果了.
if(visit[Qes[u][i]]==1)
{
//printf("%d/n",ancestor[find(Qes[u][i])]);
sum[ancestor[find(Qes[u][i])]]++;
//return;
}
}
}
int main()
{
int n;
while(scanf("%d",&n)!=EOF)
{
init(n);
int s,t,num;
char a,b,c;
for(int i=1;i<=n;i++)
{
scanf(" %d%c%c%d%c ",&s,&a,&b,&num,&c);
for(int j=1;j<=num;j++)
{
scanf("%d",&t);
tree[s].push_back(t);
indegree[t]++;
}
}
scanf("%d ",&num);
for(int i=1;i<=num;i++)
{
scanf(" %c %d %d %c",&a,&s,&t,&b);//这里可以输入多组询问
Qes[s].push_back(t);//相当于询问两次
Qes[t].push_back(s);
}
for(int i=1;i<=n;i++)
{ //寻找根节点
if(indegree[i]==0)
{
LCA(i);
break;
}
}
for(int i=1;i<=n;i++)
if(sum[i]!=0)
printf("%d:%d/n",i,sum[i]);
}
return 0;
}