HDU 4707 Pet 邻接表实现

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4707

 

解题报告:题目大意是在无向图G中有n个点,分别从0 到n-1编号,然后在这些点之间有n-1条边,可以保证这个图是连通图,并且每条边的长度都是1,然后让你求出从编号为0的点出发,到其它的点的距离大于d的点的个数。

这题的点的个数有500000个,而内存限制为32M,很显然,开邻接矩阵不行,但这题实际上不需要记录边只需要开一位数组就可以了,但是我为了练习一下邻接矩阵的写法,特地用邻接矩阵另外写了一个代码。第一次写邻接矩阵,一开始忘了标记已经走过的点,造成dfs的时候陷入了死循环,一运行就挂了,很明显爆栈了,找了好久,才发现原来走过的点如果不标记还会再走一遍。还有一个很重要的点就是,每组数据结束之后,不要忘记清理内存,不然还是会MLE。然后这题如果不用邻接表写的话,直接定义一个一位数组也行,因为题目虽然没有说,但是实际上题目输入的数据是有顺序的,就是按照从0点开始往其它的点走的顺序来输入的,很显然,这样就方便多了。

 

邻接表AC代码:

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<iostream>
 4 using namespace std;
 5 const int maxn = 100005;
 6 
 7 struct Node
 8 {
 9     int d;
10     Node *next;
11 };
12 
13 typedef struct node
14 {
15     int num;
16     Node * next;
17     node()
18     {
19         num = 0;
20         next = NULL;
21     }
22 }LinkList;
23 
24 int length[maxn],visit[maxn];
25 
26 void push(LinkList *Link,int s,int e)
27 {
28     int k = Link[s].num - 1;
29     Node *p = Link[s].next;
30     Node *q = new Node;
31     q->d = e;
32     q->next = NULL;
33     if(p == NULL)
34     Link[s].next = q;
35     else
36     {
37         while(k--)
38         p = p->next;
39         p->next = q;
40     }
41     Link[s].num++;
42 }
43 void Delete(Node *p)
44 {
45     if(p == NULL)
46     return ;
47     Delete(p->next);
48     delete p;
49 }
50 
51 void clean(LinkList *Link,int n)
52 {
53     for(int i = 0;i < n;++i)
54     Delete(Link[i].next);
55 }
56         
57 void dfs(LinkList *head,int l,int deep)
58 {
59     length[l] = deep;
60     visit[l] = 1;
61     int k = head[l].num;
62     Node *p = head[l].next;
63     while(p != NULL)
64     {
65         if(visit[p->d] == 0)
66         dfs(head,p->d,deep+1);
67         p = p->next; 
68     }
69 }
70 
71 int main()
72 {
73     int T,n,d,a,b;
74     scanf("%d",&T);
75     while(T--)
76     {
77         LinkList Link[maxn];
78         scanf("%d%d",&n,&d);
79         for(int i = 1;i<n;++i)
80         {
81             scanf("%d%d",&a,&b);
82             push(Link,a,b);
83             push(Link,b,a);
84         }
85         memset(length,0,sizeof(length));
86         memset(visit,0,sizeof(visit));
87         dfs(Link,0,0);
88         int tot = 0;
89         for(int i = 1;i < n;++i)
90         if(length[i] > d)
91         tot++;
92         printf("%d\n",tot);
93         clean(Link,n);
94     }
95     return 0;
96 }
View Code

一维数组AC代码:

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<iostream>
 4 using namespace std;
 5 
 6 const int maxn = 100005;
 7 int len[maxn];
 8 
 9 int main()
10 {
11     int T,n,d,s,e;
12     scanf("%d",&T);
13     while(T--)
14     {
15         scanf("%d %d",&n,&d);
16         memset(len,0,sizeof(len));
17         for(int i = 1;i < n;++i)
18         {
19             scanf("%d %d",&s,&e);
20             if(len[s]) len[e] = len[s] + 1;
21             else if(s == 0) len[e] = 1;
22             else ;
23         }
24         int tot = 0;
25         for(int i = 1;i < n;++i)
26         if(len[i] > d)
27         tot++;
28         printf("%d\n",tot);
29     }
30     return 0;
31 }
View Code

 

posted @ 2013-09-10 22:10  xiaxiaosheng  阅读(291)  评论(0编辑  收藏  举报