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 }
使用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 }
本人原创文章,转载请注明出处:http://www.cnblogs.com/TaoTaoCome/p/4719282.html