Time Limit: 2000MS | Memory Limit: 10000K | |
Total Submissions: 13370 | Accepted: 4338 |
Description
Input
Output
Sample Input
5 5:(3) 1 4 2 1:(0) 4:(0) 2:(1) 3 3:(0) 6 (1 5) (1 4) (4 2) (2 3) (1 3) (4 3)
Sample Output
2:1 5:5
Hint
Source
模板题
1 /* *********************************************** 2 Author :kuangbin 3 Created Time :2013-9-5 8:54:16 4 File Name :F:\2013ACM练习\专题学习\LCA\POJ1470.cpp 5 ************************************************ */ 6 7 #include <stdio.h> 8 #include <string.h> 9 #include <iostream> 10 #include <algorithm> 11 #include <vector> 12 #include <queue> 13 #include <set> 14 #include <map> 15 #include <string> 16 #include <math.h> 17 #include <stdlib.h> 18 #include <time.h> 19 using namespace std; 20 const int MAXN = 1010; 21 int rmq[2*MAXN];//rmq数组,就是欧拉序列对应的深度序列 22 struct ST 23 { 24 int mm[2*MAXN]; 25 int dp[2*MAXN][20];//最小值对应的下标 26 void init(int n) 27 { 28 mm[0] = -1; 29 for(int i = 1;i <= n;i++) 30 { 31 mm[i] = ((i&(i-1)) == 0)?mm[i-1]+1:mm[i-1]; 32 dp[i][0] = i; 33 } 34 for(int j = 1; j <= mm[n];j++) 35 for(int i = 1; i + (1<<j) - 1 <= n; i++) 36 dp[i][j] = rmq[dp[i][j-1]] < rmq[dp[i+(1<<(j-1))][j-1]]?dp[i][j-1]:dp[i+(1<<(j-1))][j-1]; 37 } 38 int query(int a,int b)//查询[a,b]之间最小值的下标 39 { 40 if(a > b)swap(a,b); 41 int k = mm[b-a+1]; 42 return rmq[dp[a][k]] <= rmq[dp[b-(1<<k)+1][k]]?dp[a][k]:dp[b-(1<<k)+1][k]; 43 } 44 }; 45 //边的结构体定义 46 struct Edge 47 { 48 int to,next; 49 }; 50 Edge edge[MAXN*2]; 51 int tot,head[MAXN]; 52 53 int F[MAXN*2];//欧拉序列,就是dfs遍历的顺序,长度为2*n-1,下标从1开始 54 int P[MAXN];//P[i]表示点i在F中第一次出现的位置 55 int cnt; 56 57 ST st; 58 void init() 59 { 60 tot = 0; 61 memset(head,-1,sizeof(head)); 62 } 63 void addedge(int u,int v)//加边,无向边需要加两次 64 { 65 edge[tot].to = v; 66 edge[tot].next = head[u]; 67 head[u] = tot++; 68 } 69 void dfs(int u,int pre,int dep) 70 { 71 F[++cnt] = u; 72 rmq[cnt] = dep; 73 P[u] = cnt; 74 for(int i = head[u];i != -1;i = edge[i].next) 75 { 76 int v = edge[i].to; 77 if(v == pre)continue; 78 dfs(v,u,dep+1); 79 F[++cnt] = u; 80 rmq[cnt] = dep; 81 } 82 } 83 void LCA_init(int root,int node_num)//查询LCA前的初始化 84 { 85 cnt = 0; 86 dfs(root,root,0); 87 st.init(2*node_num-1); 88 } 89 int query_lca(int u,int v)//查询u,v的lca编号 90 { 91 return F[st.query(P[u],P[v])]; 92 } 93 bool flag[MAXN]; 94 int Count_num[MAXN]; 95 int main() 96 { 97 //freopen("in.txt","r",stdin); 98 //freopen("out.txt","w",stdout); 99 int n; 100 int u,v,k; 101 int Q; 102 while(scanf("%d",&n) == 1) 103 { 104 init(); 105 memset(flag,false,sizeof(flag)); 106 for(int i = 1;i <= n;i++) 107 { 108 scanf("%d:(%d)",&u,&k); 109 while(k--) 110 { 111 scanf("%d",&v); 112 flag[v] = true; 113 addedge(u,v); 114 addedge(v,u); 115 } 116 } 117 int root; 118 for(int i = 1;i <= n;i++) 119 if(!flag[i]) 120 { 121 root = i; 122 break; 123 } 124 LCA_init(root,n); 125 memset(Count_num,0,sizeof(Count_num)); 126 scanf("%d",&Q); 127 while(Q--) 128 { 129 char ch; 130 cin>>ch; 131 scanf("%d %d)",&u,&v); 132 Count_num[query_lca(u,v)]++; 133 } 134 for(int i = 1;i <= n;i++) 135 if(Count_num[i] > 0) 136 printf("%d:%d\n",i,Count_num[i]); 137 } 138 return 0; 139 }