- #include<cstdio>
- #include<cstring>
- const int N = 910;
- struct Edge{
- int e,next;
- }edge[2*N];
- int n,m,e_num,head[N],vis[N],cnt[N];
- int x[N*N],y[N*N],f[N*N];
- void AddEdge(int a,int b){
- edge[e_num].e=b; edge[e_num].next=head[a]; head[a]=e_num++;
- edge[e_num].e=a; edge[e_num].next=head[b]; head[b]=e_num++;
- }
- int findx(int x){
- if(f[x]!=x)return f[x]=findx(f[x]);
- return f[x];
- }
- void tarjan(int k){
- int i;
- vis[k]=1;
- f[k]=k;
- for(i=1;i<=m;i++){//遍历处理刚才保存的 m 个询问
- if(x[i]==k && vis[y[i]])cnt[findx(y[i])]++;
- if(y[i]==k && vis[x[i]])cnt[findx(x[i])]++;
- }
- for(i=head[k];i!=-1;i=edge[i].next){
- if(!vis[edge[i].e]){
- tarjan(edge[i].e);
- f[edge[i].e]=k;
- }
- }
- }
- int main()
- {
- int i,t,id,a,flag[N];
- char ch1[2],ch2[2],ch3[2];
- while(~scanf("%d",&n))
- {
- e_num=0;
- for(i=1;i<=n;i++){
- flag[i]=vis[i]=cnt[i]=0;
- head[i]=-1;
- }
- for(i=1;i<=n;i++){
- scanf("%d%1s%1s%d%1s",&id,ch1,ch2,&t,ch3);
- while(t--){
- scanf("%d",&a);
- flag[a]=1;
- AddEdge(id,a);
- }
- }
- scanf("%d",&m);
- for(i=1;i<=m;i++)
- scanf("%1s%d%d%1s",ch1,&x[i],&y[i],ch2);
- for(i=1;i<=n;i++)//注意,这里,根节点不一定是 1
- if(flag[i]==0)break;
- tarjan(i);
- for(i=1;i<=n;i++)
- if(cnt[i])printf("%d:%d\n",i,cnt[i]);
- }
- return 0;
- }
POJ1470 LCA(tarjan离线求最近公共祖先)
最新推荐文章于 2018-07-29 11:47:33 发布