POJ 1330 Nearest Common Ancestors&&POJ1470 Closest Common Ancestors最近公共祖先 LCA
poj 1330 http://poj.org/problem?id=1330
最基础的了吧
代码:
#include<iostream> #include<cstdio> #include<string> #include<cstring> #define nMAX 10005 using namespace std; int head[nMAX],parent[nMAX]; bool vs[nMAX],use[nMAX],fg; int s_edge,n,start,end; struct Edge { int v,nxt; }edge[nMAX]; void addedge(int u,int v) { edge[++s_edge].v=v; edge[s_edge].nxt=head[u]; head[u]=s_edge; } //递归找根节点 int find(int u) { if(parent[u]==-1)return u; return parent[u]=find(parent[u]); } //tarjan void tarjan(int u) { if(fg)return ; vs[u]=1; if(u==end&&vs[start]==1) {printf("%d\n",find(start)); fg=1; return ;} if(u==start&&vs[end]==1) {printf("%d\n",find(end)); fg=1; return ;} for(int e=head[u];e;e=edge[e].nxt) { int v=edge[e].v; if(!vs[v]) { tarjan(v); parent[v]=u; } } } void init() { memset(head,0,sizeof(head)); memset(parent,-1,sizeof(parent)); memset(vs,0,sizeof(vs)); memset(use,0,sizeof(use)); s_edge=0; fg=0; } int main() { int CASE,i,j,k; scanf("%d",&CASE); while(CASE--) { init(); scanf("%d",&n); for(k=1;k<n;k++) { scanf("%d%d",&i,&j); addedge(i,j); use[j]=1; } scanf("%d%d",&start,&end); for(i=1;i<=n;i++) if(!use[i])break; tarjan(i); } return 0; }
POJ 1470
http://poj.org/problem?id=1470
输入和存储得注意
代码:
#include<iostream> #include<cstdio> #include<string> #include<cstring> #include<algorithm> #define nMAX 905 using namespace std; int head1[nMAX],head2[nMAX],parent[nMAX],ans[nMAX*nMAX],ret[nMAX]; bool vs[nMAX],use[nMAX]; int s_edge1,s_edge2,n; struct Edge1 { int v,nxt; }edge1[nMAX*nMAX]; struct Edge2 { int v,w,nxt; }edge2[nMAX*nMAX]; void addedge1(int u,int v) { edge1[++s_edge1].v=v; edge1[s_edge1].nxt=head1[u]; head1[u]=s_edge1; } void addedge2(int u,int v,int w) { edge2[++s_edge2].v=v; edge2[s_edge2].w=w; edge2[s_edge2].nxt=head2[u]; head2[u]=s_edge2; edge2[++s_edge2].v=u; edge2[s_edge2].w=w; edge2[s_edge2].nxt=head2[v]; head2[v]=s_edge2; } void init() { memset(vs,0,sizeof(vs)); memset(use,0,sizeof(use)); memset(parent,-1,sizeof(parent));//初始化为-1 memset(head1,0,sizeof(head1)); memset(head2,0,sizeof(head2)); s_edge1=0; s_edge2=0; } int find(int u) { if(parent[u]==-1)return u; return parent[u]=find(parent[u]); } void tarjan(int u) { int i,v,w,e; vs[u]=1; for(e=head2[u];e;e=edge2[e].nxt) { v=edge2[e].v; w=edge2[e].w; if(vs[v]) { ans[w]=find(v); } } for(e=head1[u];e;e=edge1[e].nxt) { v=edge1[e].v; if(!vs[v]) { tarjan(v); parent[v]=u; } } } int main() { int i,j,cnt,k,m; while(~scanf("%d",&n)) { init(); for(i=1;i<=n;i++) { scanf("%d:(%d)",&j,&cnt); while(cnt--) { scanf("%d",&k); addedge1(j,k); use[k]=1;//不是根节点 } } scanf("%d",&m); for(k=1;k<=m;k++) { scanf(" (%d %d)", &i, &j); //开始scanf("(%d %d)", &x, &y) 怎么输怎么错呀!!! addedge2(i,j,k); } for(i=1;i<=n;i++)//找根节点 if(!use[i])break; tarjan(i); sort(ans+1,ans+m+1); memset(ret,0,sizeof(ret)); for(i=1;i<=m;i++) ret[ans[i]]++; for(i=1;i<=n;i++) if(ret[i]!=0)printf("%d:%d\n",i,ret[i]); } return 0; }