題目鏈接:http://acm.hdu.edu.cn/showproblem.php?pid=5326
題意:給m對朋友構成一個樹,詢問子樹(包括孫輩)個數爲k的有幾個
思路:賽中小夥伴有類似於並查集的方法構造樹,同時統計每個的子樹有幾個,ac的,賽後自己敲的時候用鄰接矩陣構造的鏈表來寫,類似於二分匹配的時候用的鏈表,同時用l數組和r數組記錄每個點以及這個點的子樹
代碼:
小夥伴的並查集構造樹
#include <iostream>
#include <algorithm>
#include <cmath>
#include <cstring>
#include <cstdio>
#include <iomanip>
#include <queue>
#define maxn 105
using namespace std;
int pre[maxn],cnt[maxn];
int main()
{
int a,b,n,k,ans;
while(scanf("%d%d",&n,&k)!=EOF)
{
ans=0;
for(int i=1; i<=n; i++)//初始化
{
pre[i]=i;
cnt[i]=0;
}
for(int i=0; i<n-1; i++)//題意初始化
{
scanf("%d%d",&a,&b);
pre[b]=a;
}
for(int i=1; i<=n; i++)//並查集部分採用
{
int top=i;
while(top!=pre[top])
{
cnt[pre[top]]++;
top=pre[top];
}
}
for(int i=1; i<=n; i++)//找結果
{
if(cnt[i]==k)
{
ans++;
}
}
printf("%d\n",ans);
}
return 0;
}
鏈表構造樹:
#include<stdio.h>
#include<algorithm>
#include<iostream>
#include<string.h>
#define maxn 1000005
using namespace std;
int head[maxn];
int index;
int l[maxn],r[maxn];
int idx;
int id[maxn];
struct edge
{
int to,next;
}e[maxn];
void addedge(int a,int b)
{
e[index].to=b;
e[index].next=head[a];
head[a]=index;
index++;
}
void dfs(int u)
{
id[u]=++idx;
l[u]=idx;
for(int i=head[u];i!=-1;i=e[i].next)
dfs(e[i].to);
r[u]=idx;
}
int main()
{
int n,k;
int u,v;
while(scanf("%d%d",&n,&k)!=EOF)
{
index=0;
memset(head,-1,sizeof(head));
for(int i=0;i<n-1;i++)
{
scanf("%d%d",&u,&v);
addedge(u,v);
}
dfs(1);
//for(int i=1;i<=n;i++)cout<<l[i]<<" "<<r[i]<<endl;
int sum=0;
for(int i=1;i<=n;i++)
{
if(r[i]-l[i]==k)
sum++;
}
printf("%d\n",sum);
}
return 0;
}