传送门
题意:求最近公共祖先,按编号,如果是输出编号和个数。
思路:一般思路,记录个数。
跑了900+ms。。。。。。。
#include<iostream> #include<cstdio> #include<cstring> using namespace std; int n,m,fst[1000],next[1000],node[1000],x[1000000],y[1000000],num,rot[1000],cnt[1000],father[1000]; bool vis[1000]; int find(int i) { if(father[i]==i)return i; else return find(father[i]); } void LCA(int u) { father[u]=u; for(int i=fst[u];i!=-1;i=next[i]) { LCA(node[i]); father[node[i]]=u; } vis[u]=1; for(int i=0;i<m;i++) { if(u==x[i]&&vis[y[i]]) { cnt[find(y[i])]++; } else if(u==y[i]&&vis[x[i]]) { cnt[find(x[i])]++; } } } int main() { int u,v; while(scanf("%d",&n)!=EOF) { num=0; memset(fst,-1,sizeof(fst)); memset(vis,0,sizeof(vis)); memset(rot,0,sizeof(rot)); memset(cnt,0,sizeof(cnt)); for(int i=0;i<n;i++) { scanf("%d:(%d)",&u,&m); for(int j=0;j<m;j++) { scanf("%d",&v); next[++num]=fst[u]; fst[u]=num; node[num]=v; rot[v]=1; } } scanf("%d",&m); for(int i=0;i<m;i++) { while(getchar()!='('); scanf("%d %d)",&x[i],&y[i]); } for(int i=1;i<=n;i++) { if(!rot[i]) { LCA(i); break; } } for(int i=1;i<=n;i++) { if(cnt[i]) { printf("%d:%d\n",i,cnt[i]); } } } return 0; }