码迷,mamicode.com
首页 > 其他好文 > 详细

CF611H New Year and Forgotten Tree

时间:2020-01-27 19:12:49      阅读:78      评论:0      收藏:0      [点我收藏+]

标签:include   scanf   mat   +=   利用   就是   hal   固定   i+1   

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\n",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

标签:include   scanf   mat   +=   利用   就是   hal   固定   i+1   

原文地址:https://www.cnblogs.com/cjoierShiina-Mashiro/p/12236389.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!