题意:给定一棵树,然后有m个询问,最后统计公共祖先个数。
析:LCA,但是这个题输入太麻烦了,调试了好久,才出结果,然后就在Tarjan算法中直接统计就好了,刚开始MLE,后来又RE,没办法又换了一种方法才AC。
代码如下:
#pragma comment(linker, "/STACK:1024000000,1024000000") #include <cstdio> #include <string> #include <cstdlib> #include <cmath> #include <iostream> #include <cstring> #include <set> #include <queue> #include <algorithm> #include <vector> #include <map> #include <cctype> #include <cmath> #include <stack> #define freopenr freopen("in.txt", "r", stdin) #define freopenw freopen("out.txt", "w", stdout) using namespace std; typedef long long LL; typedef pair<int, int> P; const int INF = 0x3f3f3f3f; const double inf = 0x3f3f3f3f3f3f; const double PI = acos(-1.0); const double eps = 1e-8; const int maxn = 9e2 + 5; const int mod = 1e9 + 7; const int dr[] = {-1, 0, 1, 0}; const int dc[] = {0, 1, 0, -1}; const char *de[] = {"0000", "0001", "0010", "0011", "0100", "0101", "0110", "0111", "1000", "1001", "1010", "1011", "1100", "1101", "1110", "1111"}; int n, m; const int mon[] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; const int monn[] = {0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; inline int Min(int a, int b){ return a < b ? a : b; } inline int Max(int a, int b){ return a > b ? a : b; } inline LL Min(LL a, LL b){ return a < b ? a : b; } inline LL Max(LL a, LL b){ return a > b ? a : b; } inline bool is_in(int r, int c){ return r >= 0 && r < n && c >= 0 && c < m; } vector<int> G[maxn]; vector<int> q[maxn]; int ans[maxn], p[maxn]; bool vis[maxn], in[maxn]; int Find(int x){ return x == p[x] ? x : p[x] = Find(p[x]); } void Tarjan(int u){ vis[u] = true; for(int i = 0; i < q[u].size(); ++i){ int v = q[u][i]; if(vis[v]) ++ans[Find(v)]; } for(int i = 0; i < G[u].size(); ++i){ int v = G[u][i]; if(!vis[v]){ Tarjan(v); p[v] = u; } } } int main(){ while(scanf("%d", &n) == 1){ for(int i = 1; i <= n; ++i) G[i].clear(), q[i].clear(), p[i] = i; memset(in, false, sizeof in); int u, v; for(int i = 0; i < n; ++i){ scanf("%d:(%d)", &u, &m); while(m--){ scanf("%d", &v); in[v] = true; G[u].push_back(v); G[v].push_back(u); } } char s[5]; scanf("%d", &m); while(m--){ scanf("%1s%d %d%1s", s, &u, &v, s); q[u].push_back(v); q[v].push_back(u); } memset(ans, 0, sizeof ans); memset(vis, false, sizeof vis); for(int i = 1; i <= n; ++i) if(!in[i]){ Tarjan(i); break; } for(int i = 1; i <= n; ++i) if(ans[i]) printf("%d:%d\n", i, ans[i]); } return 0; }