hiho1067

题目链接:https://hihocoder.com/problemset/problem/1067

参考:http://blog.csdn.net/tree__water/article/details/60965438

稍微加了点注释。

 1 #include<cstdio>
 2 #include<iostream>
 3 #include<map>
 4 #include<vector>
 5 const int maxn=100010;
 6 using namespace std;
 7 string a,b;
 8
 9 map<string,int> pic;  //将字符串映射成数字,便于后续操作
10 vector<int> edge[maxn],py[maxn],num[maxn];
11         //  存边      查询关系   查询序号(离线之后按顺序输出用)
12 string trans[maxn]; //将数字转成对应的字符串
13
14 int vis[maxn]={0},in[maxn]={0},f[maxn]={0},ans[maxn]={0};
15                 //  入度       父亲         记录公共祖先序号
16 int gf(int x)
17 {
18     return x==f[x]?f[x]:f[x]=gf(f[x]);
19 }
20
21 void dfs(int u)
22 {
23     f[u]=u;
24     int len=edge[u].size();
25     for(int i=0;i<len;i++)
26     {
27         dfs(edge[u][i]);
28         f[edge[u][i]]=u;
29     }
30     vis[u]=1;  //子节点已全访问
31     len=py[u].size();
32     for(int i=0;i<len;i++)  //遍历相关的查询节点
33     {
34         if(vis[py[u][i]])  //如果访问过
35             ans[num[u][i]]=gf(py[u][i]); //找父亲
36     }
37
38 }
39
40 int main()
41 {
42     int n,m;
43     int cnt=0;
44     cin>>n;
45     while(n--)
46     {
47         cin>>a>>b;
48         if(!pic[a]) pic[a]=++cnt,trans[cnt]=a; //将字符串转成数字,并记录该数字对应的字符串
49         if(!pic[b]) pic[b]=++cnt,trans[cnt]=b;
50         int id1=pic[a];
51         int id2=pic[b];
52         in[id2]++;
53         edge[id1].push_back(id2);  //加边
54     }
55
56     cin>>m;
57     for(int i=0;i<m;i++)
58     {
59         cin>>a>>b;
60         int id1=pic[a];
61         int id2=pic[b];
62         py[id1].push_back(id2); //记录查询关系
63         py[id2].push_back(id1);
64         num[id1].push_back(i);  //记录输出顺序
65         num[id2].push_back(i);
66     }
67     for(int i=1;i<=cnt;i++)
68         if(in[i]==0)
69         dfs(i);
70     for(int i=0;i<m;i++)  //桉顺序输出
71         cout<<trans[ans[i]]<<endl;
72 }
时间: 2024-10-29 19:11:50

hiho1067的相关文章

最近公共祖先 - 离线处理

hiho1067 题目链接 问树上两个点的最近公共祖先 ------------------------------------------------------------------------------------------------------- 第一次写所谓的离线算法,不是来一个询问就处理一下,而是在扫描树的过程中每扫到一个点就处理和这个点相关的询问. 因为这个点的祖先肯定都访问过一次了,且所有标记为1的点都是这个点的祖先 第一次扫到这个点时标记为1,扫完这个点的所有子节点后标