POJ1470 Closest Common Ancestors 【Tarjan的LCA】

非常裸的模版题,只是Tarjan要好好多拿出来玩味几次

非常有点巧妙呢,tarjan,大概就是当前结点和它儿子结点的羁绊

WA了俩小时,,,原因是,这个题是多数据的(还没告诉你T,用scanf!=EOF来控制结束),更重要的是和这个和Codeforces不一样,Codeforces的多组数据好像会又一次開始程序似的,不用在程序里面写清零,但这个题是多数据用EOF来控制输入的,多数据在一个文件中都一次输进去了,所以要memset

btw,加上一点memset代码,多了700B代码。。。

#include <cstdio>
#include <cstdlib>
#include <iostream>
#include <algorithm>
#include <cstring>
#include <cmath>
#include <vector>
using namespace std;
const int MAXN=1111;
int n;
int in[MAXN];
vector<int> G[MAXN];
int ques[MAXN][MAXN];
bool vis[MAXN];
int fa[MAXN];
int countn[MAXN];
int father(int x)
{
	if(x==fa[x])
		return x;
	return x=father(fa[x]);
}
void dfs(int x)
{
	fa[x]=x;
	for(int i=0;i<G[x].size();i++)
	{
		dfs(G[x][i]);
		fa[G[x][i]]=x;
	}
	vis[x]=true;
	for(int i=1;i<=n;i++)
	{
		if(ques[x][i]&&vis[i])
		{
			countn[father(i)]+=ques[x][i];
		}
	}
}
int main()
{
	#ifndef ONLINE_JUDGE
		freopen("G:/1.txt","r",stdin);
		freopen("G:/2.txt","w",stdout);
	#endif
	while(scanf("%d",&n)==1)
    {
        memset(ques,0,sizeof(ques));
        memset(vis,0,sizeof(vis));
        memset(fa,0,sizeof(fa));
        memset(countn,0,sizeof(countn));
        memset(in,0,sizeof(in));
        for(int i=0;i<MAXN;i++)
        {
            G[i].clear();
        }
        for(int i=1;i<=n;i++)
        {
            int x,ynum;
            scanf("%d:(%d)",&x,&ynum);
            for(int j=1;j<=ynum;j++)
            {
                int y;
                scanf(" %d",&y);
                G[x].push_back(y);
                in[y]++;
                //G[y].push_back(x);
            }
        }
            int quesnum;
            scanf(" %d",&quesnum);
            for(int i=1;i<=quesnum;i++)
            {
                int xx,yy;
                scanf(" (%d %d)",&xx,&yy);
                ques[xx][yy]++;
                ques[yy][xx]++;
            }
            for(int i=1;i<=n;i++)
            {
                if(!in[i])
                {
                    dfs(i);
                    break;
                }
            }
            for(int i=1;i<=n;i++)
            {
                if(countn[i])
                    printf("%d:%d\n",i,countn[i]);
            }
    }
    return 0;
}


 

你可能感兴趣的:(close)