poj 1470 LCA公共祖先次数

来源:互联网 发布:创业创业软件股票行情 编辑:程序博客网 时间:2024/05/17 06:25
题意:给你树的信息,m次询问公共祖先,输出被作为祖先的次数

解法:LCA离线算法Tarjan+并查集

代码

  1. /************************************************************************* 
  2.     > File Name: poj1470.cpp 
  3.     > Author: cy 
  4.     > Mail: 1002@qq.com  
  5.     > Created Time: 14/11/9 14:50:27 
  6.  ************************************************************************/ 
  7.  
  8. #include<iostream> 
  9. #include<cstring> 
  10. #include <algorithm> 
  11. #include<cstdlib> 
  12. #include<vector> 
  13. #include<cmath> 
  14. #include<stdlib.h> 
  15. #include<iomanip> 
  16. #include<list> 
  17. #include<deque> 
  18. #include<map> 
  19. #include <stdio.h> 
  20. #include <queue> 
  21.  
  22. const int maxn=1000+5
  23.  
  24. #define inf 0x3f3f3f3f 
  25.   #define INF 0x3FFFFFFFFFFFFFFFLL 
  26. #define rep(i,n) for(i=0;i<n;i++) 
  27.  #define reP(i,n) for(i=1;i<=n;i++) 
  28.  
  29. #define ull unsigned long long 
  30.  #define ll long long 
  31.  
  32. #define cle(a) memset(a,0,sizeof(a)) 
  33.  
  34. using namespace std; 
  35. int head[maxn],used[maxn],fat[maxn],cnt[maxn],flag[maxn],Num_edge; 
  36. int m; 
  37. int x[maxn*maxn],y[maxn*maxn]; 
  38. struct Edge{ 
  39.     int to,next; 
  40. }edge[maxn*maxn]; 
  41. void add_edge(int a,int b){ 
  42.     edge[Num_edge].to=b;edge[Num_edge].next=head[a];head[a]=Num_edge++; 
  43.     edge[Num_edge].to=a;edge[Num_edge].next=head[b];head[b]=Num_edge++; 
  44. void init() 
  45.     memset(head,-1,sizeof(head)); 
  46.     cle(used);cle(cnt);cle(flag); 
  47.     Num_edge=0
  48. int get_fat(int x){ 
  49.     if(x==fat[x])return fat[x]; 
  50.     else return fat[x]=get_fat(fat[x]); 
  51. void Tarjan(int k){ 
  52.     used[k]=1
  53.     fat[k]=k; 
  54.     int i; 
  55.     rep(i,m){ 
  56.         if(x[i]==k&&used[y[i]])cnt[get_fat(y[i])]++; 
  57.         if(y[i]==k&&used[x[i]])cnt[get_fat(x[i])]++; 
  58.     } 
  59.     for(i=head[k];i!=-1;i=edge[i].next) 
  60.     { 
  61.         int to=edge[i].to; 
  62.         if(!used[to]){ 
  63.             Tarjan(to); 
  64.             fat[to]=k; 
  65.         } 
  66.     } 
  67.  
  68. char str11[2],str22[2]; 
  69. int main() 
  70. #ifndef ONLINE_JUDGE 
  71.      freopen("in.txt","r",stdin); 
  72.      //freopen("out.txt","w",stdout); 
  73. #endif 
  74.     int n; 
  75.     while(cin>>n){ 
  76.         init(); 
  77.         int a,b,t; 
  78.         int i,j; 
  79.         rep(i,n){ 
  80.             scanf("%d%1s%1s%d%1s",&a,&str11,&str11,&t,&str22); 
  81.             rep(j,t){ 
  82.                 scanf("%d",&b); 
  83.                 add_edge(a,b); 
  84.                 flag[b]++; 
  85.             } 
  86.         } 
  87.         cin>>m; 
  88.         rep(i,m){ 
  89.             scanf("%1s%d %d%1s",&str11,&a,&b,&str22); 
  90.             x[i]=a;y[i]=b; 
  91.         } 
  92.         for(i=1;i<=n;i++){ 
  93.             if(flag[i]==0){ 
  94.                 break
  95.             } 
  96.         } 
  97.         Tarjan(i); 
  98.         for(i=1;i<=n;i++){ 
  99.             if(cnt[i]){ 
  100.                 printf("%d:%d\\n",i,cnt[i]); 
  101.             } 
  102.         } 
  103.     }     
  104.     return 0
  105. }
0 0