[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\). 蒟蒻猜了一个结论:只要满足对于所有缩出来的点的子 ...
随机推荐
- typora博客笔记上传图片时不能显示
前言 markdown具有轻量化.易读易写等特性,并且对于图片.超链接.图片.数学公式都有支持. 但是最近在使用Typora的过程中我发现,在写文章笔记的时候导入的图片,因为图片保存在我们电脑本地,当 ...
- FastAPI 学习之路(三)
系列文章: FastAPI 学习之路(一)fastapi--高性能web开发框架 FastAPI 学习之路(二) 之前的文章分享了如何去创建一个简单的路径的请求.那么我们这次分享的如何在请求路径中,增 ...
- 1.2 Simple Code!(翻译)
Simple Code! 简洁编码 Playing football is very simple, but playing simple football is the hardest thing ...
- 【UE4 设计模式】抽象工厂模式 Abstract Factory Pattern
概述 描述 提供一个创建一系列相关或相互依赖对象的接口,而无须指定它们具体的类:具体的工厂负责实现具体的产品实例 抽象工厂中每个工厂可以创建多种产品(如苹果公司生产iPhone.iPad): 工厂方法 ...
- linux与windows下文件编码问题
注:转换操作均在Linux终端进行操作 DOS与Unix格式转换 安装工具:dos2unix.unix2dos # ubuntu apt-get install dos2unix apt-get in ...
- 2021.8.12考试总结[NOIP模拟37]
T1 数列 考场上切掉的简单题. $a$,$b$与数列中数的正负值对答案无关.全当作正数计算即可. $exgcd$解未知数系数为$a$,$b$,加和为$gcd(a,b)$的不定方程组,再枚举每个数.如 ...
- 零基础入门stm32基本定时器详解
一.基本定时器介绍 在STM32中,基本定时器有TIM6.TIM7等.基本定时器主要包含时基单元,提供16位的计数,能计数0~65535.基本定时器除了计数功能以外,还能输出给DAC模块一个TRGO信 ...
- 轻松掌握stm32直流电机驱动与测速
说实话就现在的市场应用中stm32已经占到了绝对住到的地位,51已经成为过去式,32的功能更加强大,虽然相应的难度有所增加,但是依然阻止不了大家学习32的脚步,不说大话了这些大家都懂要不然也不会学习s ...
- Python ImportError: cannot import name ABC
Python 3.5.2 测试可以运行 import sys from abc import ABC,abstractmethod class MyBase(ABC): @abstractmethod ...
- Python import urllib2 ImportError: No module named 'urllib2'
python3 import urllib2 import urllib2 ImportError: No module named 'urllib2' python3.3里面,用urllib.req ...