CF611H New Year and Forgotten Tree

Posted cjoiershiina-mashiro

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了CF611H New Year and Forgotten Tree相关的知识,希望对你有一定的参考价值。

Link
显然相同位数的点是完全等价的。
那么我们可以固定(1)号店为根,剩下的就是一个二分图匹配的模型了。
可以一条一条确定,利用Hall定理check确定之后是否仍然有解。
其实我也不太明白。

#include<cstdio>
#include<cstring>
int min(int a,int b){return a<b? a:b;}
int max(int a,int b){return a>b? a:b;}
int n,m,ans,id[9],cnt[9],e[9][9],is[9];char s[9],t[9];
int check()
{
    for(int i=0,x,y;i<(1<<m)-1;++i)
    {
    x=y=0;
    for(int j=0;j<m;++j) if(i>>j&1) x+=cnt[j];
    for(int j=0;j<m;++j) for(int k=j;k<m;++k) if((i>>j&1)|(i>>k&1)) y+=e[j][k];
    if(y<x) return 0;
    }
    return 1;
}
int main()
{
    scanf("%d",&n);
    for(int i=n;i;i/=10) ++m;
    for(int i=id[0]=1;i<m;++i) id[i]=id[i-1]*10;
    for(int i=0;i<m;++i) cnt[i]=id[i+1]-id[i];
    cnt[m-1]=n-id[m-1]+1;
    for(int i=1,u,v;i<n;++i) scanf("%s",s),scanf("%s",t),u=strlen(s),v=strlen(t),++e[min(u,v)-1][max(u,v)-1];
    if(!check()) return puts("-1"),0;
    --cnt[0],is[0]=1,id[0]=2;
    while(ans<n-1)
    for(int i=0;i<m;++i)
        if(is[i])
        for(int j=0;j<m;++j)
            if(cnt[j]&&e[min(i,j)][max(i,j)])
            {
            --cnt[j],--e[min(i,j)][max(i,j)];
            if(check()) printf("%d %d
",id[i]-1,id[j]),++id[j],is[j]=1,++ans;
            else ++cnt[j],++e[min(i,j)][max(i,j)];
            }
}

以上是关于CF611H New Year and Forgotten Tree的主要内容,如果未能解决你的问题,请参考以下文章

CF 750C New Year and Rating(思维题)

CF1284E New Year and Castle Construction

CF1284E New Year and Castle Construction

CF1279F New Year and Handle Change 题解

CF908G New Year and Original Order

[cf908G]New Year and Original Order