http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3602
省赛的C题,方法是hash每个节点定义的状态。
关键貌似要直接DFS递归会爆栈,所以我手写了一个栈模拟。
下面还是贴没有模拟栈之前的代码,提交会sf,不过看起来会好理解很多,模拟部分可以自己去写。
View Code
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 }
这是模拟栈后的代码,感觉自己写的不好...
View Code
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 }