题目链接:http://poj.org/problem?id=1470
Write a program that takes as input a rooted tree and a list of pairs of vertices. For each pair (u,v) the program determines the closest common ancestor of u and v in the tree. The closest common ancestor of two nodes u and v is the node w that is an ancestor of both u and v and has the greatest depth in the tree. A node can be its own ancestor (for example in Figure 1 the ancestors of node 2 are 2 and 5)
题目描述:给出一棵树的节点之间的信息,然后给出一些询问,每次询问是求出两个节点的LCA。统计每个节点被作为询问中LCA的次数并输出。
算法分析:LCA离线算法,从算法思想和思维上并不难,可以说是一道模板题,但这道题的输入有点麻烦,处理一下输入就可以了。
另外ZOJ1141也是这道题,我在ZOJ上面AC了
但是在POJ上WA了,最后处理输入之后AC了。
看看程序想了想,应该POJ上面形如5:(5)这样的输入中有可能不是冒号和括号,而是其他的符号吧。
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<cstdlib> 5 #include<cmath> 6 #include<algorithm> 7 #include<vector> 8 #define inf 0x7fffffff 9 using namespace std; 10 const int maxn=900+10; 11 const int max_log_maxn=10; 12 13 int n,root; 14 vector<int> G[maxn]; 15 int father[max_log_maxn][maxn],d[maxn]; 16 int vis[maxn]; 17 18 void dfs(int u,int p,int depth) 19 { 20 father[0][u]=p; 21 d[u]=depth; 22 int num=G[u].size(); 23 for (int i=0 ;i<num ;i++) 24 { 25 int v=G[u][i]; 26 if (v != p) dfs(v,u,depth+1); 27 } 28 } 29 30 void init() 31 { 32 dfs(root,-1,0); 33 for (int k=0 ;k+1<max_log_maxn ;k++) 34 { 35 for (int i=1 ;i<=n ;i++) 36 { 37 if (father[k][i]<0) father[k+1][i]=-1; 38 else father[k+1][i]=father[k][father[k][i] ]; 39 } 40 father[k][root]=root; 41 } 42 } 43 44 int LCA(int u,int v) 45 { 46 if (d[u]>d[v]) swap(u,v); 47 for (int k=0 ;k<max_log_maxn ;k++) 48 { 49 if ((d[v]-d[u])>>k & 1) 50 v=father[k][v]; 51 } 52 if (u==v) return u; 53 for (int k=max_log_maxn-1 ;k>=0 ;k--) 54 { 55 if (father[k][u] != father[k][v]) 56 { 57 u=father[k][u]; 58 v=father[k][v]; 59 } 60 } 61 return father[0][u]; 62 } 63 64 int main() 65 { 66 while (scanf("%d",&n)!=EOF) 67 { 68 int u,num,v; 69 for (int i=0 ;i<=n ;i++) G[i].clear(); 70 memset(vis,0,sizeof(vis)); 71 char str[100]; 72 memset(str,0,sizeof(str)); 73 char ch[2],ch2[2],ch3[2]; 74 for (int i=0 ;i<n ;i++) 75 { 76 int u=0,num=0; 77 scanf("%d%1s%1s%d%1s",&u,ch,ch2,&num,ch3); 78 // scanf("%s",str); 79 // int u=0,num=0; 80 // int len=strlen(str); 81 // int j=0; 82 // for (j=0 ;j<len && str[j]!=‘:‘;j++) u=u*10+str[j]-‘0‘; 83 // for (j=j+2 ;j<len && str[j]!=‘)‘;j++) num=num*10+str[j]-‘0‘; 84 while (num--) 85 { 86 scanf("%d",&v); 87 G[u].push_back(v); 88 vis[v]=1; 89 } 90 } 91 for (int i=1 ;i<=n ;i++) if (!vis[i]) {root=i;break; } 92 init(); 93 memset(vis,0,sizeof(vis)); 94 scanf("%d",&num); 95 memset(str,0,sizeof(str)); 96 //getchar(); 97 for (int j=0 ;j<num ;j++) 98 { 99 scanf("%1s%d%d%1s",ch,&u,&v,ch2); 100 // gets(str); 101 // int u=0,v=0; 102 // int len=strlen(str); 103 // int i=0; 104 // for (i=1 ;i<len && str[i]>=‘0‘ && str[i]<=‘9‘ ;i++) 105 // u=u*10+str[i]-‘0‘; 106 // while (i<len) 107 // { 108 // if (str[i]>=‘0‘ && str[i]<=‘9‘) break; 109 // i ++ ; 110 // } 111 // while (i<len) 112 // { 113 // if (str[i]==‘)‘) break; 114 // v=v*10+str[i]-‘0‘; 115 // i ++ ; 116 // } 117 int ans=LCA(u,v); 118 vis[ans]++; 119 } 120 for (int i=1 ;i<=n ;i++) 121 if (vis[i]) printf("%d:%d\n",i,vis[i]); 122 } 123 return 0; 124 }
时间: 2024-10-10 23:33:57