您的位置:首页 > Web前端

codeforces 690F2 Tree of Life (medium) 树hash

2016-09-05 18:57 375 查看
题意:一棵树,分别给出去掉第i个点之后剩下的图,点的顺序打乱,图的顺序打乱,求这棵树原来长什么样。n<=100

一定有一个图是去掉一个叶子节点之后的,找到这个图,枚举叶子加到哪,然后对于加完叶子的树枚举删掉一个点,把删完点的图hash出来扔到multiset里,再看其他图hash出来的值和这个multiset里的东西一不一样就行了。

无根树hash需要先找到重心,从重心hash,如果有两个重心还要在之间多加一个点。hash时将叶子的hash值排个序,hash出来就行了。

哦,顺便一提,我的是最短代码。

upd 广告:觉得这道题太水了么? 觉得树hash仅此而已了么 ?

请看下篇题解codeforces 690F3 Tree of Life (hard)。

spoiler alert : 对于下一道题可能引起的不适反应,请自备纸带。

#include <bits/stdc++.h>
using namespace std;
#define N 110
#define ull unsigned long long
#define seed 11333333
int n,T;
multiset<ull>se;
multiset<ull>::iterator it;
ull val
;
struct tree
{
int m,top,f1,f2,sum,id;
int vis
,size
,used
,f
;
vector<int>v
;
vector<ull>v1
;
ull st
;

void dfs1(int x,int y)
{
size[x]=1;used[x]=1;
for(int i=0,t;i<v[x].size();i++)
if((t=v[x][i])!=y&&!vis[t])
dfs1(t,x),size[x]+=size[t];
}
void dfs2(int x,int y)
{
f[x]=sum-size[x];
for(int i=0,t;i<v[x].size();i++)
if((t=v[x][i])!=y&&!vis[t])
dfs2(t,x),f[x]=max(f[x],size[t]);
if(f[x]<f[f1])f1=x;
else if(f[x]<f[f2])f2=x;
}
ull dfs3(int x,int y)
{
v1[x].clear();
for(int i=0,t;i<v[x].size();i++)
if((t=v[x][i])!=y&&!vis[t])
v1[x].push_back(dfs3(t,x));
sort(v1[x].begin(),v1[x].end());
ull ret=1;
for(int i=0;i<v1[x].size();i++)
ret=ret*seed+v1[x][i];
return ret;
}
ull cal(int x)
{
f1=f2=0;f[0]=1<<30;
dfs1(x,0);
sum=size[x];dfs2(x,0);
if(f[f1]!=f[f2])
return dfs3(f1,0);
ull t1=dfs3(f1,f2);
ull t2=dfs3(f2,f1);
if(t1>t2)swap(t1,t2);
return t1*seed+t2;
}
void init(int x)
{
scanf("%d",&m);id=x;
for(int i=1;i<=n;i++)v[i].clear();
for(int i=1,x,y;i<=m;i++)
{
scanf("%d%d",&x,&y);
v[x].push_back(y);
v[y].push_back(x);
}
memset(used,0,sizeof(used));
top=0;
for(int i=1;i<=n;i++)
if(!used[i])
st[++top]=cal(i);
sort(st+1,st+1+top);val[id]=0;
for(int i=2;i<=top;i++)
val[id]=val[id]*seed+st[i];
}
int check()
{
se.clear();
for(int i=1;i<=n;i++)
{
vis[i]=1;top=0;
for(int j=0;j<v[i].size();j++)
st[++top]=cal(v[i][j]);
vis[i]=0;ull tmp=0;
sort(st+1,st+1+top);
for(int j=1;j<=top;j++)
tmp=tmp*seed+st[j];
se.insert(tmp);
}
for(int i=1;i<=n;i++)
if(i!=id)
{
if((it=se.find(val[i]))==se.end())
return 0;
se.erase(it);
}
return 1;
}
void print()
{
puts("YES");
for(int i=1;i<=n;i++)
{
for(int j=0,t;j<v[i].size();j++)
if((t=v[i][j])<i)
printf("%d %d\n",t,i);
}
}
}tr
;
void solve()
{
scanf("%d%*d",&n);
for(int i=1;i<=n;i++)
tr[i].init(i);
for(int i=1;i<=n;i++)
if(tr[i].top==2)
{
for(int j=1;j<=n;j++)
if(tr[i].v[j].empty())
{
for(int k=1;k<=n;k++)
if(k!=j)
{
tr[i].v[k].push_back(j);
tr[i].v[j].push_back(k);
if(tr[i].check())
{
tr[i].print();
return;
}
tr[i].v[k].pop_back();
tr[i].v[j].pop_back();
}
}
break;
}
puts("NO");
}
int main()
{
//freopen("tt.in","r",stdin);
scanf("%d",&T);
while(T--)
{
solve();
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  codeforces hash