[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\). 蒟蒻猜了一个结论:只要满足对于所有缩出来的点的子 ...
随机推荐
- xLua中Lua调用C#
xLua中Lua调用C# 1.前提 这里使用的是XLua框架,需要提前配置xlua,设置加载器路径: 可以参考之前的Blog:<xlua入门基础>: //调用段,所有的lua代码都写在Lu ...
- 如何用redis统计海量UV?
前言 我们先思考一个常见的业务问题:如果你负责开发维护一个大型的网站,有一天老板找产品经理要网站每个网页每天的 UV 数据,然后让你来开发这个统计模块,你会如何实现? 统计uv的常用方法以及优缺点 其 ...
- 从零入门 Serverless | 架构的演进
作者 | 许晓斌 阿里云高级技术专家 本文整理自<Serverless 技术公开课>,关注"Serverless"公众号,回复 入门 ,即可获取 Serverless ...
- 利用ps在光污染地图上寻找最近的观星地区
城市灯光对于天文观测和天文摄影是有害的,进行这两类活动之前应提前规划地点,下面是笔者尝试的一种利用ps在光污染地图上进行规划的方法. 目前大部分的光污染地图都是基于WA 2015绘制的,可以结合VII ...
- 从 MVC 到使用 ASP.NET Core 6.0 的最小 API
从 MVC 到使用 ASP.NET Core 6.0 的最小 API https://benfoster.io/blog/mvc-to-minimal-apis-aspnet-6/ 2007 年,随着 ...
- Visual Studio Debug only user code with Just My Code
Debug only user code with Just My Code By default, the debugger skips over non-user code (if you wan ...
- javascript-jquery对象的其他处理
一.对元素进行遍历操作 如果要遍历一个jquery对象,对其中每个匹配元素进行相应处理,那么可以使用each()方法. $("div").each(function(index,e ...
- BPMN 學習實例
什麼是業務流程圖? What is BPMN 業務流程建模符號(BPMN)是業務流程建模的一種方法.它基於統一建模語言(UML)中活動圖的概念,以圖形符號(業務流程圖)支持業務流程的規範.BPMN為企 ...
- 记一次 .NET 某资讯论坛 CPU爆高分析
大概有11天没发文了,真的不是因为懒,本想前几天抽空写,不知道为啥最近求助的朋友比较多,一天都能拿到2-3个求助dump,晚上回来就是一顿分析,有点意思的是大多朋友自己都分析了几遍或者公司多年的牛皮藓 ...
- Ruby on Rails 单元测试
Ruby on Rails 单元测试 为什么要写测试文件? 软件开发中,一个重要的环节就是编写测试文件,对代码进行单元测试,确保程序各部分功能执行正确.但是,这一环节很容易被我们轻视,认为进行单元测试 ...