• pku1470 Closest Common Ancestors


    呵呵,这道题目的话,跟之前那道计算路径程度有点区别

    给你多个路径,让你求出哪些节点被作为最近公共祖先,并计算被作为最近公共祖先的次数

    首先,读入数据有点麻烦,按代码中那种方法,还蛮方便的

    其次就是,需要找出根节点,再进行深度优先搜索,这是很求路径长度唯一的区别,计算路径的时候,从任意节点开始,并不影响计算路径的长度

    但是,此题目中,我们要保证每一个最近公共祖先都是正确的,为什么这么说呢?因为,在计算路径的时候,其实只是一种相对的情况,即,这已遍历的节点中,相对的某个节点是最近公共祖先,没有一种严格性

    而此题就是要求最近公共祖先,所以必须先找出根节点,即入度为零的节点,这个也很好理解

    具体的,见之前的2586吧

    #include<stdio.h>
    #include<string.h>
    #include<stdlib.h>
    #define MAXN 910
    int first[MAXN],head[MAXN],cnt[MAXN],f[MAXN];
    int visited[MAXN];
    struct node
    {
    	int vex,next;
    }g[MAXN*2];
    struct node1
    {
    	int vex,next;
    }q[MAXN*MAXN];
    int find(int x)
    {
    	if(x==f[x])
    		return f[x];
    	f[x]=find(f[x]);
    	return f[x];
    }
    void add(int v,int w,int &j)
    {
    	g[j].vex=w;
    	g[j].next=first[v];
    	first[v]=j++;
    }
    void add2(int v,int w,int &j)
    {
    	q[j].vex=w;
    	q[j].next=head[v];
    	head[v]=j++;
    }
    void DFS(int v)
    {
    	f[v]=v;
    	visited[v]=1;
    	int i;
    	for(i=head[v];i!=-1;i=q[i].next)
    		if(visited[q[i].vex])//已访问
    		{
    			cnt[find(q[i].vex)]++;
    		}
    	for(i=first[v];i!=-1;i=g[i].next)
    	{
    		if(!visited[g[i].vex])
    		{
    			DFS(g[i].vex);
    			f[g[i].vex]=v;
    		}
    	}
    }
    int main()
    {
    	int m,n,i,t,v,w,j,k;
    	int flag[MAXN];
    	char ch;
    	while(scanf("%d",&n)!=EOF)
    	{
    		k=n;
    		memset(first,-1,sizeof(first));
    		memset(head,-1,sizeof(head));
    		memset(visited,0,sizeof(visited));
    		memset(cnt,0,sizeof(cnt));
    		memset(flag,0,sizeof(flag));
    		j=0;
    		while(k--)
    		{
    			scanf("%d",&v);
    			while(getchar()!='(');//很不错的读入方法
    			scanf("%d",&t);
    			while(getchar()!=')');
    			while(t--)
    			{
    				scanf("%d",&w);
    				add(v,w,j);
    				add(w,v,j);
    				flag[w]=1;
    			}
    		}
    		scanf("%d",&m);
    		for(i=j=0;i<m;i++)
    		{
    			while(getchar()!='(');
    			scanf("%d %d",&v,&w);
    			while(getchar()!=')');
    			add2(v,w,j);
    			add2(w,v,j);
    		}
    		for(i=1;i<=n;i++)
    			if(flag[i]==0)//入度为0
    				break;
    		DFS(i);
    		for(i=1;i<=n;i++)
    			if(cnt[i])
    				printf("%d:%d\n",i,cnt[i]);
    	}
    	return 0;
    }
    
  • 相关阅读:
    mini linux制作
    samba
    文件链接
    bz1234513
    shell中if判断语句
    文件系统层次结构
    ssh免密码登陆
    shell基础
    参考__Web前端大全
    参考__综合类网站大全
  • 原文地址:https://www.cnblogs.com/nanke/p/2040679.html
Copyright © 2020-2023  润新知