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; }