http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3602
省赛的C题,方法是hash每个节点定义的状态。
关键貌似要直接DFS递归会爆栈,所以我手写了一个栈模拟。
下面还是贴没有模拟栈之前的代码,提交会sf,不过看起来会好理解很多,模拟部分可以自己去写。
1 #include<iostream> 2 #include<cstdio> 3 #include<cstdlib> 4 #include<map> 5 #include<cstring> 6 using namespace std; 7 typedef long long LL; 8 #define N 100010 9 struct node{ 10 int l,r; 11 friend bool operator<(const node &x,const node &y){ 12 if(y.l!=x.l) return y.l<x.l; 13 return y.r<x.r; 14 } 15 }tree[2][N]; 16 int n,m,cs,num[2][N]; 17 map<node,int> state; 18 int id(node x){ 19 if(state.find(x)==state.end()) 20 state[x]=++cs; 21 return state[x]; 22 } 23 int dfs(int u,int kind){ 24 if(u==-1) return 0; 25 node temp; 26 temp.l=dfs(tree[kind][u].l,kind); 27 temp.r=dfs(tree[kind][u].r,kind); 28 int ans=id(temp); 29 num[kind][ans]++; 30 return ans; 31 } 32 int main(){ 33 int T,a,b; 34 scanf("%d",&T); 35 while(T--){ 36 scanf("%d%d",&n,&m); 37 for(int i=1;i<=n;++i){ 38 scanf("%d%d",&a,&b); 39 tree[0][i].l=a; 40 tree[0][i].r=b; 41 } 42 for(int i=1;i<=m;++i){ 43 scanf("%d%d",&a,&b); 44 tree[1][i].l=a; 45 tree[1][i].r=b; 46 } 47 state.clear(); 48 cs=0; 49 memset(num,0,sizeof(num)); 50 dfs(1,0); 51 dfs(1,1); 52 LL ans=0; 53 for(int i=0;i<=n+m;++i) 54 ans+=LL(num[0][i])*LL(num[1][i]); 55 printf("%lld\n",ans); 56 } 57 return 0; 58 }
这是模拟栈后的代码,感觉自己写的不好...
1 #include<iostream> 2 #include<cstdio> 3 #include<cstdlib> 4 #include<map> 5 #include<cstring> 6 using namespace std; 7 typedef long long LL; 8 #define N 100010 9 struct node{ 10 int l,r; 11 friend bool operator<(const node &x,const node &y){ 12 if(y.l!=x.l) return y.l<x.l; 13 return y.r<x.r; 14 } 15 }tree[2][N]; 16 int n,m,cs,num[2][N<<1]; 17 map<node,int> state; 18 int id(node x){ 19 if(state.find(x)==state.end()) 20 state[x]=++cs; 21 return state[x]; 22 } 23 struct stk{ 24 int u,op,st; 25 }qu[N]; 26 void dfs(int u,int kind){ 27 int top=0; 28 qu[top].u=u; 29 qu[top++].op=0; 30 while(top){ 31 stk now=qu[top-1]; 32 if(now.u==-1){ 33 qu[top-1].st=0; 34 top--; 35 } 36 else if(!now.op){ 37 qu[top].u=tree[kind][now.u].l; 38 qu[top].op=0; 39 qu[top-1].op=1; 40 top++; 41 } 42 else if(now.op==1){ 43 qu[top].u=tree[kind][now.u].r; 44 qu[top].op=0; 45 qu[top-1].op=2; 46 qu[top-1].st=qu[top].st; 47 top++; 48 } 49 else{ 50 node temp; 51 temp.l=qu[top-1].st; 52 temp.r=qu[top].st; 53 int rig=id(temp); 54 qu[top-1].st=rig; 55 num[kind][rig]++; 56 top--; 57 } 58 } 59 } 60 int main(){ 61 int T,a,b; 62 scanf("%d",&T); 63 while(T--){ 64 scanf("%d%d",&n,&m); 65 for(int i=1;i<=n;++i){ 66 scanf("%d%d",&a,&b); 67 tree[0][i].l=a; 68 tree[0][i].r=b; 69 } 70 for(int i=1;i<=m;++i){ 71 scanf("%d%d",&a,&b); 72 tree[1][i].l=a; 73 tree[1][i].r=b; 74 } 75 state.clear(); 76 cs=0; 77 memset(num,0,sizeof(num)); 78 dfs(1,0); 79 dfs(1,1); 80 LL ans=0; 81 for(int i=0;i<=cs;++i) 82 ans+=LL(num[0][i])*LL(num[1][i]); 83 printf("%lld\n",ans); 84 } 85 return 0; 86 }