zoj1141

来源:互联网 发布:Java开发dwg批量转jpg 编辑:程序博客网 时间:2024/06/06 01:37

题目大意:

写一个程序,输入一棵树。对于一对(u,v),程序决定u和v的最近公共祖先。节点也可以是自己的祖先
输出每个节点他作为公共祖先的数量

解题思路:

LCA离线算法

代码如下:

#include<iostream>#include<vector>#include<cstdio>#include<cstring>using namespace std;const int MAXN = 1001;vector<int>vec[MAXN];bool vis[MAXN];int high[MAXN],path[MAXN],res,f[MAXN];int dfs_dep(int u,int deep) {vis[u] = true;high[u] = deep;int i,len = vec[u].size();for(i=0;i<len;i++) {   if(!vis[vec[u][i]]) {    dfs_dep(vec[u][i],deep+1);   }}return 0;}int dfs(int u,int v,int deep) {int i;if(u == v) {   int minn = high[path[0]];   res = path[0];   for(i=1;i<=deep;i++) {    if(minn > high[path[i]]) {     minn = high[path[i]] , res = path[i];    }   }   return 0;}int len = vec[u].size();for(i=0;i<len;i++) {   if(!vis[vec[u][i]]) {    vis[vec[u][i]] = true;    path[deep] = vec[u][i];    dfs(vec[u][i],v,deep+1);   }}return 0;}int main(){int n,m,i,j,ind[MAXN],a,b;char ch;while(scanf("%d",&n)!=EOF) {   for(i=1;i<=n;i++) { vec[i].clear() , ind[i] = 0; }   for(i=1;i<=n;i++) {    scanf("%d",&a);    while(ch=getchar()!='(') ;    scanf("%d",&m);    while(ch=getchar()!=')') ;    for(j=1;j<=m;j++) {     scanf("%d",&b);     vec[a].push_back(b);     vec[b].push_back(a);     ind[b]++;    }   }   for(i=1;i<=n;i++)    if(!ind[i]) break;   int root = i;   memset(vis,0,sizeof(bool)*(n+1));   dfs_dep(root,0);   scanf("%d",&m);    memset(f,0,sizeof(f));   while(m--) {    while(ch=getchar()!='(');    scanf("%d %d",&a,&b);    while(ch=getchar()!=')');    if(a == b) { f[a]++; continue; }     memset(vis,0,sizeof(bool)*(n+1));    path[0] = a , vis[a] = true;    dfs(a,b,1);    f[res]++;   }   for(i=1;i<=n;i++)    if(f[i]) printf("%d:%d\n",i,f[i]);}return 0;}
0 0
原创粉丝点击