【LCA/tarjan】POJ1470-Closest Common Ancestors

【题意】

给出一棵树和多组查询,求以每个节点为LCA的查询数有多少?

【错误点】

①读入的时候,注意它的空格是随意的呀!一开始不知道怎么弄,后来看了DISCUSS区大神的话:

询问部分输入:

scanf("%d",&m);
for(int i=0;i<m;i++){
scanf(" (%d %d)",&a,&b);
}

注意scanf(" 这里有一个空格

②多组数据啊!注意这句话:
The input file contents several data sets (at least one).

③痛心疾首!它问的是以每个节点为LCA的查询数,所以查询可以重复,同样的查询可以累计!

  1 #include<iostream>
  2 #include<cstdio>
  3 #include<cstring>
  4 #include<vector>
  5 using namespace std;
  6 const int MAXN=900+5;
  7 vector<int> E[MAXN];
  8 int query[MAXN][MAXN];
  9 int cnt[MAXN];
 10 int notrt[MAXN],rt;
 11 int ance[MAXN];
 12 int vis[MAXN];
 13 int m;//结点的总个数
 14
 15 int find(int u)
 16 {
 17     int r=u;
 18     while (ance[r]!=r) r=ance[r];
 19     int ans=r;
 20     r=u;
 21     while (ance[r]!=r)
 22     {
 23         int tmp=ance[r];
 24         ance[r]=ans;
 25         r=tmp;
 26     }
 27     return ans;
 28 }
 29
 30 void tarjan(int u)
 31 {
 32     vis[u]=1;
 33     for (int v=1;v<=m;v++)
 34     {
 35         if (!query[u][v]) continue;
 36         if (vis[v])
 37         //被访问过有两种情况:一是祖先靠左的子树中的后代;或者是自己的祖先。两者的LCA均为v所在并查集的根
 38         {
 39             int LCA=find(v);
 40             cnt[LCA]+=query[u][v];
 41             //注意,允许同样的查询出现多次,并且同样的查询可以累计!
 42         }
 43     }
 44
 45     ance[u]=u;
 46     for (int i=0;i<E[u].size();i++)
 47     {
 48         int v=E[u][i];
 49         tarjan(v);
 50         ance[v]=u;
 51     }
 52 }
 53
 54 void init()
 55 {
 56     memset(query,0,sizeof(query));
 57     memset(cnt,0,sizeof(cnt));
 58     memset(notrt,0,sizeof(notrt));
 59     memset(vis,0,sizeof(vis));
 60     for (int i=1;i<=m;i++) E[i].clear();
 61     for (int i=0;i<m;i++)
 62     {
 63         int p,T;
 64         scanf("%d:(%d)",&p,&T);
 65         for (int i=0;i<T;i++)
 66         {
 67             int son;
 68             scanf(" %d",&son);
 69             E[p].push_back(son);
 70             notrt[son]++;
 71         }
 72     }
 73
 74     int n;
 75     scanf("%d",&n);
 76     for (int i=0; i<n; i++)
 77     {
 78         int a,b;
 79         scanf(" (%d %d)",&a,&b);
 80         //注意这里(前面要有一个空格!否则无法过!
 81         query[a][b]++;
 82         query[b][a]++;
 83     }
 84
 85     for (int i=1;i<=m;i++) if (!notrt[i])
 86     {
 87         rt=i;
 88         break;
 89     }
 90 }
 91
 92 void print()
 93 {
 94     for (int i=1;i<=m;i++)
 95         if (cnt[i]>0)
 96             cout<<i<<‘:‘<<cnt[i]<<endl;
 97 }
 98
 99 int main()
100 {
101     while (~scanf("%d",&m))
102     //注意是多组数据
103     {
104         init();
105         tarjan(rt);
106         print();
107     }
108     return 0;
109 }
时间: 2024-10-06 11:32:13

【LCA/tarjan】POJ1470-Closest Common Ancestors的相关文章

【LCA|Tarjan】POJ-1330 Nearest Common Ancestors

Nearest Common Ancestors Time Limit: 1000MS Memory Limit: 10000K Description A rooted tree is a well-known data structure in computer science and engineering. An example is shown below: In the figure, each node is labeled with an integer from {1, 2,-

POJ1470 Closest Common Ancestors 【Tarjan的LCA】

非常裸的模版题,只是Tarjan要好好多拿出来玩味几次 非常有点巧妙呢,tarjan,大概就是当前结点和它儿子结点的羁绊 WA了俩小时,,,原因是,这个题是多数据的(还没告诉你T,用scanf!=EOF来控制结束),更重要的是和这个和Codeforces不一样,Codeforces的多组数据好像会又一次開始程序似的,不用在程序里面写清零,但这个题是多数据用EOF来控制输入的,多数据在一个文件中都一次输进去了,所以要memset btw,加上一点memset代码,多了700B代码... #incl

Poj1470 Closest Common Ancestors LCA

LCA裸题.. #include<iostream> #include<cstdio> #include<cstring> #include<map> #include<vector> using namespace std; const int maxn = 1111; int head[maxn]; int len; struct Node { int to; int next; }e[maxn * 2]; int father[maxn];

poj 1470 Closest Common Ancestors 【Tarjan 离线 LCA】

题目:poj 1470 Closest Common Ancestors 题意:给出一个树,一些询问.求LCA的个数. 分析:很简单的模板题目,但是模板不够优秀,一直wa...RE,各种错误一下午,终于发现自己模板的漏洞了. AC代码: #include <iostream> #include <cstdio> #include <cstring> #include <vector> using namespace std; #define N 1010 #

POJ 1470 Closest Common Ancestors【最近公共祖先LCA】

题目链接:http://poj.org/problem?id=1470 题目大意:给出一棵树,再给出若干组数(a,b),输出节点a和节点b的最近公共祖先(LCA) 就是很裸的LCA,但是我用的是<挑战程序设计竞赛>上的"基于二分搜索的算法求LCA",我看网上用的都是tarjan算法.但是我的代码不知道为什么提交上去 wrong answer,自己想的很多测试数据也都和题解结果一样,不知道错在哪里,所以把代码保存一下,留待以后解决...... 如果读者有什么建议,希望提出来,

POJ 1470 Closest Common Ancestors 【LCA】

任意门:http://poj.org/problem?id=1470 Closest Common Ancestors Time Limit: 2000MS   Memory Limit: 10000K Total Submissions: 22519   Accepted: 7137 Description Write a program that takes as input a rooted tree and a list of pairs of vertices. For each pa

POJ 1470 Closest Common Ancestors LCA题解

本题也是找LCA的题目,不过要求多次查询,一般的暴力查询就必然超时了,故此必须使用更高级的方法,这里使用Tarjan算法. 本题处理Tarjan算法,似乎输入处理也挺麻烦的. 注意: 因为查询的数据会极大,故此使用一个数组记录所有查询数据就会超时的.我就载在这里了.查了好久才想到这点.因为我使用了一个vector容器记录了查询数据,故此每次都循环这组这么大的数据,就超时了.----解决办法:使用一个vector<int> quest来记录查询数组,这样每次都只需要循环某节点的邻接查询点就可以了

poj----(1470)Closest Common Ancestors(LCA)

Closest Common Ancestors Time Limit: 2000MS   Memory Limit: 10000K Total Submissions: 15446   Accepted: 4944 Description 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

POJ 题目1470 Closest Common Ancestors(LCA)

Closest Common Ancestors Time Limit: 2000MS   Memory Limit: 10000K Total Submissions: 16671   Accepted: 5319 Description 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