【题解】CF611H New Year and Forgotten Tree

神题了...

题目描述

给定你一棵树,可是每个节点上的编号看不清了,只能辨别它的长度。现在用问号的个数代表每个节点编号那个数字的长度,请你还原这一颗树,任意输出一个方案,有PSJ\(SPJ\)来检验你的正确性。无解输出一行\(-1\) 。

输入格式:

第一行一个整数\(n\)。

接下来 \(n-1\)行每行两个有问号构成的字符串,代表编号长度。

输出格式 :

若有解,直接输出\(n-1\)行,每行两个正整数,代表你还原的这颗树的边连接的两个节点。

若无解输出\(-1\)

solution_1:搜索套网络流

仔细思考一下,发现问号个数分别一样的边是本质相同的,我们把形如\((? ?\ , ??)\)这样的边先处理掉,直接连成一条链,然后把这条链看做一个点。

现在问题就变成了,给你五种不同颜色的点,相同颜色不连边,现在已知颜色两两相连的边的数目,请你构造一颗树出来。

怎么构造?可以每种颜色选定一个"关键点",先让关键点们生成一棵树,要求别的颜色连边过来必须连这一个点。我们抓出两种颜色来讨论,必须满足\(|a->b_{关键}|+|b->a_{关键}|=e[a][b]\),我们可以把所有的限制建模跑网络流,这样我们就知道从每种颜色连到另一种颜色的数目,就可以直接构造方案了。

但是有个问题,关键点之间生成的树对于答案是有影响的,所以还要先暴搜这(最多五个)点的连边情况,这个爆搜底数和指数都很小,可以当做常数。

然而我没写这种。

solution_2:Hall定理

hall定理:加入对于一个二分图存在完美匹配(已经把某一边匹配满了),设两边为\(X,Y,|X|\le|Y|\),那么在\(|X|\)中选出\(\forall k \in[0,|X|]\)个顶点,它向另一边连接的点数\(\ge k​\)。

#include<bits/stdc++.h>
using namespace std;
inline int qr(){
char c=getchar();
register int ret=0,f=0;
while(not isdigit(c)) f|=c==45,c=getchar();
while(isdigit(c)) ret=ret*10+c-48,c=getchar();
return f?-ret:ret;
}
inline int qrqr(){
register char c=getchar();
register int ret=0;
while(c^'?')c=getchar();
while(c=='?')++ret,c=getchar();
return ret;
}
const int maxn=9;
int ten[maxn];
int e[maxn][maxn];
int cnt[maxn];
bool in[maxn];
#define pb(x,y) push_back(make_pair(x,y))
vector < pair< int , int > > ve;
int n,m; inline bool chek(){
for(register int t=0,edd=(1<<m)-1;t<edd;++t){
int a(0),b(0);
for(register int i=0;i<m;++i)
if(t>>i&1) b+=cnt[i+1];
for(register int f=0;f<m;++f)
for(register int g=f;g<m;++g)
if((t>>f&1)|(t>>g&1))
a+=e[f+1][g+1];
if(a<b) return 0;
}
return 1;
} int main(){
freopen("Manchester.in","r",stdin);
freopen("Manchester.out","w",stdout);
int sav=qr();
n=sav;
ten[1]=1;
for(register int t=2;t<=6;++t) ten[t]=ten[t-1]*10;
while(sav) sav/=10,++m;
for(register int t=1,t1,t2;t< n;++t){
t1=qrqr();t2=qrqr();
++e[t1][t2];
if(t1^t2)++e[t2][t1];
}
for(register int t=1;t<=5;++t) cnt[t]=ten[t+1]-ten[t];
cnt[m]=n-ten[m]+1;
if(not chek()) return puts("-1"),0;
--cnt[1],in[1]=1,++ten[1];
while(sav<n-1){
for(register int t=1;t<=m;++t){
if(in[t])
for(register int i=1;i<=m;++i){
if(!e[i][t] || !cnt[i]) continue;
--e[i][t],--cnt[i];
if(t^i) --e[t][i];
if(chek()){
ve.pb(ten[t]-1,ten[i]);
++ten[i];in[i]=1;++sav;
}
else {
++e[i][t],++cnt[i];
if(t^i) ++e[t][i];
}
}
}
}
for(auto t:ve)
printf("%d %d\n",t.first,t.second);
return 0;
}

【题解】CF611H New Year and Forgotten Tree的更多相关文章

  1. [cf611H]New Year and Forgotten Tree

    首先,来构造这棵树的形态 称位数相同的点为一类点,从每一类点中任选一个点,具有以下性质: 1.每一类中选出的点的导出子图连通(是一颗树) 2.每一条边必然有一个端点属于某一类中选出的点 (关于&quo ...

  2. 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 ...

  3. 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 ...

  4. IndiaHacks 2016 - Online Edition (Div. 1 + Div. 2) E - Bear and Forgotten Tree 2 链表

    E - Bear and Forgotten Tree 2 思路:先不考虑1这个点,求有多少个连通块,每个连通块里有多少个点能和1连,这样就能确定1的度数的上下界. 求连通块用链表维护. #inclu ...

  5. 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 ...

  6. 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 ...

  7. 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 ...

  8. 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 ...

  9. 题解 CF611H 【New Year and Forgotten Tree】

    Solution 提供一种新思路. 首先考虑如何判断一个状态是否合法. 考虑把所有十进制长度一样的数缩成一个点. 这样的点的个数 \(\le 5\). 蒟蒻猜了一个结论:只要满足对于所有缩出来的点的子 ...

随机推荐

  1. Flume、Kafka、Storm结合

    Todo: 对Flume的sink进行重构,调用kafka的消费生产者(producer)发送消息; 在Sotrm的spout中继承IRichSpout接口,调用kafka的消息消费者(Consume ...

  2. C# mvc统一通道使用过滤器

    问题描述 使用C#过滤器有一个最大的问题就是在过滤器转向后程序仍然会执行方法体 问题解决思路 使用统一通道执行方法 不直接进入控制器 通过反射调用 using System; using System ...

  3. Eclips中文版或汉化使用

    Eclipse简体中文包下载地址 :http://babel.eclipse.org/babel/ 在上面网站找,下载地址应该是(注意对应的版本): http://www.eclipse.org/do ...

  4. 10张思维导图带你学习【Java​Script】

    思维导图小tips:思维导图又叫心智图.是表达发射性思维的有效的图形思维工具 ,它简单却又极其有效,是一种革命性的思维工具.思维导图运用图文并重的技巧.把各级主题的关系用相互隶属与相关的层级图表现出来 ...

  5. atitit.Atitit.检测文本文件的编码 java  与php版  。Net

    atitit.Atitit.检测文本文件的编码 java  与php版  .Net 1 检测编码原理 Utf8>>gbk 在此转会gbk>>utf 2 工具检测编码 不能使用l ...

  6. cpu分析简介

    进程占用CPU过高,一般有以下两种原因:          1.    业务量过大导致进程处理负荷高,占用CPU资源:2.    程序BUG导致,比如死循环:    初步查看cpu占用情况top进一步 ...

  7. ARM处理器的运行模式

    ARM处理器的7种运行模式 用户模式( usr ):ARM处理器正常的程序执行状态: 快速中断模式( fiq ):用于高速数据传输或通道处理: 外部中断模式( irq):用于通常的中断处理: 管理模式 ...

  8. redis 底层数据结构 压缩列表 ziplist

    压缩列表是列表键和哈希键的底层实现之一.当一个列表键只包含少量列表项,并且每个列表项要么就是小整数,要么就是长度比较短的字符串,redis就会使用压缩列表来做列表键的底层实现 当一个哈希键只包含少量键 ...

  9. 集合映射中的映射包(使用xml文件)

    如果持久类有List对象,我们可以通过列表或者bag元素在映射文件中映射. 这个包(bag)就像List一样,但它不需要索引元素. 在这里,我们使用论坛的场景: 论坛中一个问题有多个答案. 我们来看看 ...

  10. goldengate原理与简单配置

    goldengate的原理:http://www.ipresst.com/works/52bc44c42954a7d73b0003f2 简单单向配置: 在oracle官网下载下载 GoldenGate ...