POJ 1470
标准的LCA,输入感觉怪怪的=.=
自己看了下Tarjan,再参考了下别人的处理方法(感觉自己好弱。。)
#include <iostream> #include <cstdio> #include <cmath> #include <cstring> using namespace std; const int N = 1010; const int M = 1000010; int in[N], par[N], ans[N]; bool vis[N]; int n, edge, m; struct ST { int top; int next[M],key[M],head[N]; void add(int x,int y) { key[top] = y; //记录儿子 next[top] = head[x]; head[x] = top++; } void clear() { top = 0; memset(head,-1,sizeof(head)); } }son,q; int fin(int x) { if(x != par[x]) par[x] = fin(par[x]); return par[x]; } void lca(int cur) { par[cur] = cur; for(int i = son.head[cur];i != -1;i = son.next[i]) { lca(son.key[i]); par[son.key[i]] = cur; } vis[cur] = true; for(int i = q.head[cur];i!= -1;i = q.next[i]) { if(vis[q.key[i]]) ans[fin(q.key[i])]++; } } void ini() { memset(in,0,sizeof(in)); memset(vis,false,sizeof(vis)); memset(ans,0,sizeof(ans)); } int main() { int root, u, num, v; while(scanf("%d", &n) != EOF) { ini(); son.clear(), q.clear(); for(int j = 0; j < n; ++j) { scanf("%d:(%d)", &u, &num); for(int i = 0; i < num; ++i) { scanf("%d", &v); son.add(u, v); in[v]++; } } for(root = 1;in[root];root++); scanf("%d",&m); while(m--) { scanf(" (%d %d)", &u, &v); if(u == v) q.add(v, u); else { q.add(u, v); q.add(v, u); } } lca(root); for(int i = 1;i <= n;i++) if(ans[i]) printf("%d:%d ", i, ans[i]); } return 0; }