ZSTU OJ 3999 零基础学算法---邻接表

题目:Click here

 

题意:我就喜欢中文题!

分析:这个题虽然是中文题,但是还是有一点费解的。其实就是给你一棵树,是用图的形式给你的,只知道a,b之间有一条边,并不知道谁是父,谁是子。思路就是先把这个无向图用邻接表存下来,再转成有向图,最后dfs回答每一条询问。

模拟链表实现的邻接表:

 

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 const int INF = 0x3f3f3f3f;
 4 const int M = 1178706+3;
 5 
 6 struct Edge {   // 邻接表的结点
 7     int v, next;
 8 }edge[M<<1];
 9 
10 int n, root, E, q;
11 int cnt;
12 bool vis[M];
13 int head[M];    // 邻接表头结点
14 
15 void newedge( int u, int v )    {   // 连接一条边
16     edge[E].v = v;
17     edge[E].next = head[u];
18     head[u] = E;
19     E++;
20 }
21 
22 void dfschaneg( int root )   {  // 将无向图转换成有向图
23     vis[root] = true;
24     for( int i=head[root]; i!=-1; i=edge[i].next )
25         if( !vis[edge[i].v] )   dfschaneg( edge[i].v );
26         else   edge[i].v = INF;     // 将访问过的点标记INF,之后dfs时就不会再访问了
27 }
28 
29 void dfs( int pos ) {   // dfs遍历子树
30     cnt++;
31     for( int i=head[pos]; i!=-1; i=edge[i].next )
32         if( edge[i].v != INF )
33             dfs( edge[i].v );
34 }
35 
36 int main()  {
37     #ifdef ONLINE_JUDGE
38     #else
39         freopen( "in.txt", "r", stdin );
40     #endif
41     while( ~scanf("%d %d", &n, &root ) )    {
42         E = 0;
43         memset( vis, false, sizeof(vis) );
44         memset( head, -1, sizeof(head) );
45         for( int i=1; i<n; i++ )    {
46             int x, y;
47             scanf("%d %d", &x, &y );
48             newedge( x, y );    // 由于是无向图,所以x到y,y到x都有边
49             newedge( y, x );
50         }
51         dfschaneg( root );
52         scanf("%d", &q );
53         for( int i=0; i<q; i++ )    {
54             int pos;
55             scanf("%d", &pos );
56             cnt = 0;
57             dfs( pos );
58             printf("%d\n", cnt );
59         }
60     }
61     return 0;
62 }
View Code

 

使用vector实现的邻接表:

 

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstring> 
 4 #include <algorithm>
 5 #include <vector> 
 6 #define pb push_back
 7 using namespace std;
 8 const int M = 1e4+5;
 9 const int INF = 0x3f3f3f3f;
10 
11 int n, root, q;
12 vector<int> v[M];   // vector实现的邻接表,v[i]这个vector存的是与i邻接的顶点
13 bool vis[M];
14 int cnt;
15 
16 void dfschange( int pos )  {    // 将无向图转换成有向图
17     vis[pos] = true;
18     for( int i=0; i<v[pos].size(); i++ )    {
19         if( !vis[v[pos][i]] )    {
20             dfschange( v[pos][i] );
21         }
22         else    {
23             v[pos][i] = INF;    // 将访问过的点标记INF,之后dfs时就不会再访问了
24         }
25     }
26     return ;
27 }
28 
29 void dfs( int x )   {
30     cnt++;
31     for( int i=0; i<v[x].size(); i++ )    {
32         if( v[x][i] != INF )
33             dfs( v[x][i] );
34     }
35     return ;
36 }
37 
38 int main()  {
39     while( ~scanf("%d %d", &n, &root ) )    {
40         for( int i=0; i<M; i++ )    {
41             v[i].clear();
42         }
43         for( int i=0; i<n-1; i++ )  {
44             int x, y;
45             scanf("%d %d", &x, &y );
46             v[x].pb(y);     // 由于是无向图,所以x到y,y到x都有边
47             v[y].pb(x);
48         }
49         memset( vis, false, sizeof(vis) );
50         dfschange( root );
51         scanf("%d", &q );
52         for( int i=0; i<q; i++ )    {
53             int x;
54             scanf("%d", &x );
55             cnt = 0;
56             dfs( x );
57             printf("%d\n", cnt );
58         }
59     }    
60     return 0;
61 }
View Code

 

 本人原创文章,转载请注明出处:http://www.cnblogs.com/TaoTaoCome/p/4719282.html

posted @ 2015-08-10 21:20  TaoTaoCome  阅读(434)  评论(0编辑  收藏  举报