您的位置:首页 > 其它

zoj 3602 Count the Trees

2012-04-15 14:59 323 查看
http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3602

省赛的C题,方法是hash每个节点定义的状态。

关键貌似要直接DFS递归会爆栈,所以我手写了一个栈模拟。

下面还是贴没有模拟栈之前的代码,提交会sf,不过看起来会好理解很多,模拟部分可以自己去写。

View Code

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<map>
#include<cstring>
using namespace std;
typedef long long LL;
#define N 100010
struct node{
int l,r;
friend bool operator<(const node &x,const node &y){
if(y.l!=x.l) return y.l<x.l;
return y.r<x.r;
}
}tree[2]
;
int n,m,cs,num[2][N<<1];
map<node,int> state;
int id(node x){
if(state.find(x)==state.end())
state[x]=++cs;
return state[x];
}
struct stk{
int u,op,st;
}qu
;
void dfs(int u,int kind){
int top=0;
qu[top].u=u;
qu[top++].op=0;
while(top){
stk now=qu[top-1];
if(now.u==-1){
qu[top-1].st=0;
top--;
}
else if(!now.op){
qu[top].u=tree[kind][now.u].l;
qu[top].op=0;
qu[top-1].op=1;
top++;
}
else if(now.op==1){
qu[top].u=tree[kind][now.u].r;
qu[top].op=0;
qu[top-1].op=2;
qu[top-1].st=qu[top].st;
top++;
}
else{
node temp;
temp.l=qu[top-1].st;
temp.r=qu[top].st;
int rig=id(temp);
qu[top-1].st=rig;
num[kind][rig]++;
top--;
}
}
}
int main(){
int T,a,b;
scanf("%d",&T);
while(T--){
scanf("%d%d",&n,&m);
for(int i=1;i<=n;++i){
scanf("%d%d",&a,&b);
tree[0][i].l=a;
tree[0][i].r=b;
}
for(int i=1;i<=m;++i){
scanf("%d%d",&a,&b);
tree[1][i].l=a;
tree[1][i].r=b;
}
state.clear();
cs=0;
memset(num,0,sizeof(num));
dfs(1,0);
dfs(1,1);
LL ans=0;
for(int i=0;i<=cs;++i)
ans+=LL(num[0][i])*LL(num[1][i]);
printf("%lld\n",ans);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: