Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 1754 Accepted Submission(s): 847
1 #include<stdio.h> 2 #include<string.h> 3 #include<vector> 4 using namespace std; 5 vector<int>vec[100010]; 6 int dis[100010]; 7 void dfs(int x){ 8 for(int i=0;i<vec[x].size();i++){ 9 dis[vec[x][i]]=dis[x]+1;//深度加一;vec【x】【i】代表b的值也就是dis【b】等于a的深度加一; 10 dfs(vec[x][i]);//如果vec[x].size()不为0;下一步搜索,改变深度的值;下次就是b了; 11 } 12 return; 13 } 14 int main(){ 15 int T,N,D,a,b,flot; 16 scanf("%d",&T); 17 while(T--){memset(dis,0,sizeof(dis));flot=0; 18 scanf("%d%d",&N,&D); 19 for(int i=0;i<N;i++)vec[i].clear(); 20 for(int i=0;i<N-1;i++){ 21 scanf("%d%d",&a,&b); 22 vec[a].push_back(b); 23 } 24 dfs(0); 25 for(int i=0;i<N;i++){ 26 if(dis[i]>D)flot++; 27 } 28 printf("%d\n",flot); 29 } 30 return 0; 31 }
自己写的邻接表:
1 #include<stdio.h> 2 #include<string.h> 3 struct Node{ 4 int now; 5 int next; 6 int step; 7 }; 8 Node map[100010]; 9 int head[100010]; 10 int len,anser,N,D;//每次加一代表的是当前树的总结点数 11 void add(int x,int y){ 12 map[len].now=y;//now放第二个 y 13 map[len].next=head[x];//next指向第一个x;也就是y指向x; 14 head[x]=len++; 15 } 16 void dfs(int x,int st){ 17 if(st>D)anser++;//深度大于D答案就++; 18 for(int i=head[x];i!=-1;i=map[i].next){//相当于vector的size,这个以链表的查找方式; 19 map[i].step=st+1; 20 dfs(map[i].now,map[i].step);//将当前搜索到的与head[i]相接的now传下去,继续搜索; 21 } 22 return; 23 } 24 int main(){ 25 int T,a,b; 26 scanf("%d",&T); 27 while(T--){len=0;anser=0; 28 memset(map,0,sizeof(map)); 29 memset(head,-1,sizeof(head));//将head数组的初始化为-1 30 scanf("%d%d",&N,&D); 31 for(int i=0;i<N-1;i++){ 32 scanf("%d%d",&a,&b); 33 add(a,b); 34 } 35 dfs(0,0); 36 printf("%d\n",anser); 37 } 38 return 0; 39 }
自己写的并查集:
1 #include<stdio.h> 2 const int MAXN=100010; 3 int tree[MAXN]; 4 int N,D; 5 int find(int x){ 6 int r=x; 7 while(r!=tree[r])r=tree[r]; 8 return r; 9 } 10 int depth(int x){int tot=0; 11 while(x!=tree[x]){ 12 x=tree[x];tot++; 13 } 14 return tot; 15 } 16 void initial(){ 17 for(int i=0;i<=N;i++)tree[i]=i; 18 } 19 void merge(int x,int y){ 20 tree[y]=x;//由于是找深度,没有路径压缩,所以直接并上; 21 } 22 int findanswer(){int answer=0; 23 for(int i=N;i>0;i--){ 24 if(depth(i)>D&&find(i)==0)answer++; 25 // printf("%d\n",depth(i)); 26 } 27 return answer; 28 } 29 int main(){ 30 int T,a,b,answer; 31 scanf("%d",&T); 32 while(T--){ 33 scanf("%d%d",&N,&D); 34 initial(); 35 for(int i=0;i<N-1;i++){ 36 scanf("%d%d",&a,&b); 37 merge(a,b); 38 } 39 answer=findanswer(); 40 printf("%d\n",answer); 41 } 42 return 0; 43 }
大神们用的邻接表和并差集先贴着吧;有空自己写写:
邻接表:
1 #include <stdio.h> 2 #include <string.h> 3 #include <algorithm> 4 using namespace std; 5 struct node 6 { 7 int next,to; 8 int step; 9 }a[100005]; 10 int head[100005]; 11 int n,d,len,ans; 12 void add(int x,int y) 13 { 14 a[len].to = y; 15 a[len].next = head[x]; 16 head[x] = len++; 17 } 18 void dfs(int x,int step) 19 { 20 int i,j,k; 21 if(-1 == head[x]) 22 return ; 23 for(i = head[x]; i!=-1; i = a[i].next) 24 { 25 k = a[i].to; 26 a[i].step = step+1; 27 if(a[i].step>d) 28 ans++; 29 dfs(k,a[i].step); 30 } 31 } 32 int main() 33 { 34 int T,i,j,x,y; 35 scanf("%d",&T); 36 while(T--) 37 { 38 memset(head,-1,sizeof(head)); 39 memset(a,0,sizeof(a)); 40 scanf("%d%d",&n,&d); 41 len = 0; 42 for(i = 1; i<n; i++) 43 { 44 scanf("%d%d",&x,&y); 45 add(x,y); 46 } 47 ans = 0; 48 dfs(0,0); 49 printf("%d\n",ans); 50 }
并差集:
1 #include<stdio.h> 2 #include<string.h> 3 #include<iostream> 4 #include<algorithm> 5 #define MAXN 110000 6 using namespace std; 7 int pri[MAXN]; 8 int sum,m; 9 int find(int x) 10 { 11 int r=x; 12 while(r!=pri[r]) 13 r=pri[r]; 14 return r; 15 } 16 int num(int a) 17 { 18 int b=0; 19 while(a!=pri[a]) 20 { 21 a=pri[a]; 22 b++; 23 } 24 return b; 25 } 26 void fun() 27 { 28 for(int i=MAXN;i>0;i--) 29 { 30 if(find(i)==0&&num(i)>m)//根节点为0且距离大于m 31 sum++; 32 } 33 } 34 int main() 35 { 36 int n,i,a,b,t; 37 scanf("%d",&t); 38 while(t--) 39 { 40 sum=0; 41 for(i=0;i<MAXN;i++) 42 pri[i]=i; 43 scanf("%d%d",&n,&m); 44 for(i=0;i<n-1;i++) 45 { 46 scanf("%d%d",&a,&b); 47 pri[b]=a;//直接并,不用查 48 } 49 fun(); 50 printf("%d\n",sum); 51 } 52 return 0; 53 }