[cf611H]New Year and Forgotten Tree
首先,来构造这棵树的形态
称位数相同的点为一类点,从每一类点中任选一个点,具有以下性质:
1.每一类中选出的点的导出子图连通(是一颗树)
2.每一条边必然有一个端点属于某一类中选出的点
(关于“若有解,一定存在上述这种形式的解”的证明可能比较困难,大概感性理解一下?)
由于类别很少(记为$m=\lfloor\log_{10}n\rfloor+1$),$o(m^{m-2})$或$o{\frac{(m+1)m}{2}\choose m-1}$暴力确定这$m$类点中选出的点的树形态(实际差不了多少),接下来每一条边相当于可以使边端点中的一类未在连通块中加入连通块,即如果记$s_{x}$表示$x$类点剩余的点数量,之后每一条边相当于选择$s_{x}$或$s_{y}$减小1
很明显是一个网络流的模型,判一下是否满流即可,复杂度大概可过
1 #include<bits/stdc++.h>
2 using namespace std;
3 #define N 200005
4 #define M 7
5 #define oo 0x3f3f3f3f
6 #define fi first
7 #define se second
8 struct ji{
9 int nex,to,len;
10 }edge[M*M*M];
11 queue<int>q;
12 vector<pair<int,int> >ansE;
13 int V,E,n,m,head[M*M],len[N],a[M][M],id[M][M],tot[M],pos[M],now[M],f[M],d[M*M],work[M*M];
14 char s1[M],s2[M];
15 int find(int k){
16 if (k==f[k])return k;
17 return find(f[k]);
18 }
19 void add(int x,int y,int z){
20 edge[E].nex=head[x];
21 edge[E].to=y;
22 edge[E].len=z;
23 head[x]=E++;
24 if (E&1)add(y,x,0);
25 }
26 bool bfs(){
27 memset(d,oo,sizeof(d));
28 d[0]=0;
29 q.push(0);
30 while (!q.empty()){
31 int k=q.front();
32 q.pop();
33 for(int i=head[k];i!=-1;i=edge[i].nex)
34 if ((edge[i].len)&&(d[edge[i].to]==oo)){
35 d[edge[i].to]=d[k]+1;
36 q.push(edge[i].to);
37 }
38 }
39 return d[V+m+1]<oo;
40 }
41 int dfs(int k,int s){
42 if (k>V+m)return s;
43 for(int &i=work[k];i!=-1;i=edge[i].nex)
44 if ((edge[i].len)&&(d[edge[i].to]==d[k]+1)){
45 int p=dfs(edge[i].to,min(s,edge[i].len));
46 if (p){
47 edge[i].len-=p;
48 edge[i^1].len+=p;
49 return p;
50 }
51 }
52 return 0;
53 }
54 int dinic(){
55 int k,ans=0;
56 while (bfs()){
57 memcpy(work,head,sizeof(work));
58 while (k=dfs(0,oo))ans+=k;
59 }
60 return ans;
61 }
62 bool dfs(int k,int x,int y){
63 if (k>=m){
64 E=0;
65 memset(head,-1,sizeof(head));
66 for(int i=1;i<=m;i++)
67 for(int j=i;j<=m;j++){
68 add(0,id[i][j],a[i][j]);
69 add(id[i][j],V+i,oo);
70 add(id[i][j],V+j,oo);
71 }
72 for(int i=1;i<=m;i++)add(V+i,V+m+1,tot[i]);
73 if (dinic()==n-m){
74 for(int i=1;i<=m;i++)
75 for(int j=i;j<=m;j++)
76 for(int k=head[id[i][j]];k!=-1;k=edge[k].nex)
77 if (edge[k].to>V){
78 int p=edge[k].to-V;
79 for(int l=edge[k].len;l<oo;l++)ansE.push_back(make_pair(++now[p],pos[i+j-p]));
80 }
81 return 1;
82 }
83 return 0;
84 }
85 for(int i=x;i<=m;i++)
86 for(int j=y;j<=m;j++)
87 if ((a[i][j])&&(find(i)!=find(j))){
88 int ii=find(i);
89 f[ii]=j;
90 a[i][j]--;
91 ansE.push_back(make_pair(pos[i],pos[j]));
92 if (dfs(k+1,i,j))return 1;
93 f[ii]=ii;
94 a[i][j]++;
95 ansE.pop_back();
96 }
97 return 0;
98 }
99 int main(){
100 scanf("%d",&n);
101 for(int i=1;i<n;i++){
102 scanf("%s%s",s1,s2);
103 int x=strlen(s1),y=strlen(s2);
104 if (x>y)swap(x,y);
105 a[x][y]++;
106 }
107 for(int i=1;i<=n;i++){
108 len[i]=len[i/10]+1;
109 tot[len[i]]++;
110 }
111 m=len[n];
112 for(int i=1;i<=m;i++)tot[i]--;
113 pos[1]=1;
114 for(int i=2;i<=m;i++)pos[i]=pos[i-1]*10;
115 memcpy(now,pos,sizeof(now));
116 for(int i=1;i<=m;i++)f[i]=i;
117 for(int i=1;i<=m;i++)
118 for(int j=i;j<=m;j++)id[i][j]=++V;
119 if (!dfs(1,1,1))printf("-1");
120 else{
121 for(int i=0;i<ansE.size();i++)printf("%d %d\n",ansE[i].fi,ansE[i].se);
122 }
123 }
[cf611H]New Year and Forgotten Tree的更多相关文章
- 【题解】CF611H New Year and Forgotten Tree
[题解]CF611H New Year and Forgotten Tree 神题了... 题目描述 给定你一棵树,可是每个节点上的编号看不清了,只能辨别它的长度.现在用问号的个数代表每个节点编号那个 ...
- IndiaHacks 2016 - Online Edition (Div. 1 + Div. 2) E - Bear and Forgotten Tree 2 链表
E - Bear and Forgotten Tree 2 思路:先不考虑1这个点,求有多少个连通块,每个连通块里有多少个点能和1连,这样就能确定1的度数的上下界. 求连通块用链表维护. #inclu ...
- VK Cup 2016 - Round 1 (Div. 2 Edition) C. Bear and Forgotten Tree 3 构造
C. Bear and Forgotten Tree 3 题目连接: http://www.codeforces.com/contest/658/problem/C Description A tre ...
- IndiaHacks 2016 - Online Edition (Div. 1 + Div. 2) E. Bear and Forgotten Tree 2 bfs set 反图的生成树
E. Bear and Forgotten Tree 2 题目连接: http://www.codeforces.com/contest/653/problem/E Description A tre ...
- Code Forces Bear and Forgotten Tree 3 639B
B. Bear and Forgotten Tree 3 time limit per test2 seconds memory limit per test256 megabytes inputst ...
- Codeforces 639B——Bear and Forgotten Tree 3——————【构造、树】
Bear and Forgotten Tree 3 time limit per test 2 seconds memory limit per test 256 megabytes input st ...
- codeforces 658C C. Bear and Forgotten Tree 3(tree+乱搞)
题目链接: C. Bear and Forgotten Tree 3 time limit per test 2 seconds memory limit per test 256 megabytes ...
- VK Cup 2016 - Round 1 (Div. 2 Edition) C. Bear and Forgotten Tree 3
C. Bear and Forgotten Tree 3 time limit per test 2 seconds memory limit per test 256 megabytes input ...
- 题解 CF611H 【New Year and Forgotten Tree】
Solution 提供一种新思路. 首先考虑如何判断一个状态是否合法. 考虑把所有十进制长度一样的数缩成一个点. 这样的点的个数 \(\le 5\). 蒟蒻猜了一个结论:只要满足对于所有缩出来的点的子 ...
随机推荐
- IO之字节流
什么是字节流 像操作 图片 视频 mp4 文档(里面可能有图片) 等等 注意点 必须使用try catch finally 来包 不用throws(流是要关闭的 如果中途抛错 throws 无法将流关 ...
- Python中pymongo find 遍历数据导致timeout
背景 在读取大约200W左右的数据的时候采用游标形式进行数据遍历时,超过10分钟就报错 timeout 原因 pymongo游标会在10分钟之后被关闭 解决方案 db.find({}, no_curs ...
- Billu_b0x内网渗透-vulnhub
个人博客:点我 本次来试玩一下vulnhub上的Billu_b0x,只有一个flag,下载地址. 下载下来后是 .ova 格式,建议使用vitualbox进行搭建,vmware可能存在兼容性问题.靶场 ...
- Flask的环境配置
Flask django是大而全,提供所有常用的功能 flask是小而精,只提供核心功能 环境配置 为了防止 django和 flask环境相互冲突,可以使用 虚拟环境分割开 pip instal ...
- 经典论文系列 | 缩小Anchor-based和Anchor-free检测之间差距的方法:自适应训练样本选择
前言 本文介绍一篇CVPR2020的论文,它在paperswithcode上获得了16887星,谷歌学术上有261的引用次数. 论文主要介绍了目标检测现有的研究进展.anchor-based和 ...
- 什么,你还使用 webpack?别人都在用 vite 搭建项目了
一.vite 到底是干嘛的? vite 实际上就是一个面向现代浏览器,基于 ES module 实现了一个更轻快的项目构建打包工具. vite 是法语中轻快的意思. vite 的特点: 1.轻快的冷服 ...
- k8s replicaset controller分析(2)-核心处理逻辑分析
replicaset controller分析 replicaset controller简介 replicaset controller是kube-controller-manager组件中众多控制 ...
- Stack2 攻防世界题目分析
---XCTF 4th-QCTF-2018 前言,怎么说呢,这题目还是把我折磨的可以的,我一开始是没有看到后面的直接狙击的,只能说呢. 我的不经意间的粗心,破坏了你许多的温柔 1.气的我直接检查保护: ...
- HDI PCB一阶和二阶和三阶如何区分??
一阶板,一次压合即成,可以想像成最普通的板二阶板,两次压合,以盲埋孔的八层板为例,先做2-7层的板,压好,这时候2-7的通孔埋孔已经做好了,再加1层和8层压上去,打1-8的通孔,做成整板.三阶板就 ...
- stm32看门狗详细解答,看了觉得一下子明白了很多
一.独立看门狗 STM32 的独立看门狗由内部专门的 40Khz 低速时钟驱动,即使主时钟发生故障,它也仍然有效. 看门狗的原理:单片机系统在外界的干扰下会出现程序跑飞的现象导致出现死循环,看门狗电路 ...