csu 1837: Tree Count

来源:互联网 发布:浙江省软件考试 编辑:程序博客网 时间:2024/05/18 03:38

题目链接点这里

大意:给你n课树,点上有权值(可以转化为边上权值),,从小到大输出各个同构类中树的个数

,,xjb Hash一下。。不过输入有点坑,,看了看天才看懂的,,第一行每2个数字代表一条边,不确定有几个

#include<cstdio>#include<cstring>#include<map>#include<sstream>#include<iostream>#include<math.h>#include<algorithm>#include<queue>using namespace std;#define MX  77777#define INF 0x3f3f3f3f#define INFLL 0x3f3f3f3f3f3f3f3f#define mem(x,y) memset(x,y,sizeof(x))#define fuck(x)  cout<<x<<endltypedef  unsigned long long ULL;typedef  pair<int,int > PII;const ULL PA=11111;const ULL PB=31111;int n;int head[MX],cnt;struct Edge{    int to,nxt;} E[2*MX];void edge_init(){    mem(head,-1);    cnt=0;}void edge_add(int u,int v){    E[cnt].to=v;    E[cnt].nxt=head[u];    head[u]=cnt++;}ULL H[MX];int val[MX];int sz[MX];int root1,root2,maxn;void find_root(int u,int fa){    int ma=0;    sz[u]=1;    for(int i=head[u]; ~i; i=E[i].nxt)    {        int v=E[i].to;        if(v==fa) continue;        find_root(v,u);        ma=max(ma,sz[v]);        sz[u]+=sz[v];    }    ma=max(ma,n-sz[u]);    if(ma<maxn) maxn=ma,root1=u,root2=-1;    else if(ma==maxn) root2=u;}map<ULL,int> mp;void Hash(int u,int fa){    if(fa==-1) H[u]=PA;    else H[u]=(ULL)(val[fa]-val[u])^PA;    for(int i=head[u]; ~i; i=E[i].nxt)    {        int v=E[i].to;        if(v==fa) continue;        Hash(v,u);        H[u]*=H[v]^PB;    }}bool lof;bool Int(int &a){    if(lof) return lof=0;    char c;    for(c=getchar(); c<'0'||c>'9'; c=getchar())if(c=='\n')return 0;    a=c-'0';    for(c=getchar(); c>='0'&&c<='9'; c=getchar())a=a*10+c-'0';    lof=c=='\n';    return 1;}int main(){    freopen("input.txt","r",stdin);    int T;    while(~scanf("%d",&T))    {        mp.clear();        for(int i=1; i<=T; i++)        {            edge_init();            getchar();            int u,v;            n=1;            lof=0;            while(Int(u))            {                Int(v);                n++;                edge_add(u,v);                edge_add(v,u);            }            for(int i=1; i<=n; i++) scanf("%d",&val[i]);            maxn=INF;            root1=root2=-1;            find_root(1,-1);            ULL w;            Hash(root1,-1);            w=H[root1];            if(root2!=-1)            {                Hash(root2,-1);                w=min(w,H[root2]);            }            mp[w]++;        }        vector<int> ans;        for(auto i:mp) ans.push_back(i.second);        sort(ans.begin(),ans.end());        for(int i=0; i<ans.size(); i++)printf("%d%c",ans[i],i==ans.size()-1?'\n':' ');    }    return 0;}


0 0