Time Limit: 2000MS | Memory Limit: 10000K | |
Total Submissions: 14915 | Accepted: 4745 |
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
思路:离线lca ,利用tarjan算法。
tarjan算法的步骤是(当dfs到节点u时):
1. 在并查集中建立仅有u的集合,设置该集合的祖先为u
2. 对u的每个孩子v:
2.1 tarjan之
2.2 合并v到父节点u的集合,确保集合的祖先是u
3. 设置u为已遍历
4. 处理关于u的查询,若查询(u,v)中的v已遍历过,则LCA(u,v)=v所在的集合的祖先
14006525 | njczy2010 | 1470 | Accepted | 2992K | 516MS | G++ | 1979B | 2015-03-25 19:29:20 |
1 #include <cstdio> 2 #include <cstring> 3 #include <stack> 4 #include <vector> 5 #include <algorithm> 6 7 #define ll long long 8 int const N = 1005; 9 int const M = 205; 10 int const inf = 1000000000; 11 ll const mod = 1000000007; 12 13 using namespace std; 14 15 int n,m; 16 vector<int> bian[N]; 17 vector<int> query[N]; 18 int cnt[N]; 19 int fa[N]; 20 int vis[N]; 21 int degree[N]; 22 23 int findfa(int x) 24 { 25 return fa[x] == x ? fa[x] : fa[x] = findfa(fa[x]); 26 } 27 28 void ini() 29 { 30 int i,j; 31 int k,u,v; 32 memset(cnt,0,sizeof(cnt)); 33 memset(vis,0,sizeof(vis)); 34 memset(degree,0,sizeof(degree)); 35 for(i=1;i<=n;i++){ 36 bian[i].clear(); 37 query[i].clear(); 38 fa[i]=i; 39 } 40 for(i=1;i<=n;i++){ 41 scanf("%d:(%d)",&u,&k); 42 for(j=0;j<k;j++){ 43 scanf("%d",&v); 44 bian[u].push_back(v); 45 degree[v]++; 46 } 47 } 48 scanf("%d",&m); 49 for(i=1;i<=m;i++){ 50 while(getchar()!=‘(‘) ; 51 scanf("%d%d",&u,&v); 52 while(getchar()!=‘)‘) ; 53 query[u].push_back(v); 54 query[v].push_back(u); 55 } 56 } 57 58 void tarjan(int u,int f) 59 { 60 vector<int>::iterator it; 61 int v; 62 for(it=bian[u].begin();it!=bian[u].end();it++){ 63 v=*it; 64 tarjan(v,u); 65 } 66 67 for(it=query[u].begin();it!=query[u].end();it++){ 68 v=*it; 69 if(vis[v]==0) continue; 70 cnt[ findfa(v) ]++; 71 } 72 vis[u]=1; 73 fa[u]=f; 74 } 75 76 void solve() 77 { 78 int i; 79 for(i=1;i<=n;i++){ 80 if(degree[i]==0){ 81 tarjan(i,-1); 82 } 83 } 84 } 85 86 void out() 87 { 88 int i; 89 for(i=1;i<=n;i++){ 90 // printf("%d:%d\n",i,cnt[i]); 91 if(cnt[i]!=0){ 92 printf("%d:%d\n",i,cnt[i]); 93 } 94 } 95 } 96 97 int main() 98 { 99 //freopen("data.in","r",stdin); 100 //scanf("%d",&T); 101 // for(cnt=1;cnt<=T;cnt++) 102 //while(T--) 103 while(scanf("%d",&n)!=EOF) 104 { 105 ini(); 106 solve(); 107 out(); 108 } 109 }
poj1470 Closest Common Ancestors [ 离线LCA tarjan ]
原文:http://www.cnblogs.com/njczy2010/p/4366700.html