有趣啊~手玩一下这棵树,发现因为连边只对相连点的位数有限制,我们可以认为是在往一棵已经有 m 个结点的树上挂叶子结点直到满足要求。(m = log(10) n)。注意由于 m 超级无敌小,我们可以直接爆搜初始树,然后 dinic 二分图匹配即可。(网络流:一边的点表示限制,另一边的点表示位数。每一条限制可以删去一个节点, 检验一下是否能够删完即可)。

#include <bits/stdc++.h>
using namespace std;
#define maxn 300000
#define INF 9999999
int n, m, cal[maxn], num[maxn], cur[maxn];
int tot, mark[][], rec[][], lev[maxn];
int S, T, Q[maxn], d[maxn], deg[maxn];
char s1[maxn], s2[maxn];
priority_queue <int, vector <int>, greater <int> > q; int read()
{
int x = , k = ;
char c; c = getchar();
while(c < '' || c > '') { if(c == '-') k = -; c = getchar(); }
while(c >= '' && c <= '') x = x * + c - '', c = getchar();
return x * k;
} struct edge
{
int cnp, to[maxn], last[maxn], head[maxn], f[maxn], F[maxn];
edge() { cnp = ; }
void add(int u, int v, int fl)
{
// cout << "*****" << u << " " << v << " " << fl << endl;
to[cnp] = v, f[cnp] = F[cnp] = fl, last[cnp] = head[u], head[u] = cnp ++;
to[cnp] = u, f[cnp] = F[cnp] = , last[cnp] = head[v], head[v] = cnp ++;
}
}E1; struct node
{
int u, v;
}id[maxn]; bool bfs()
{
queue <int> q;
memset(lev, , sizeof(lev)); lev[S] = ;
q.push(S);
while(!q.empty())
{
int u = q.front(); q.pop();
for(int i = E1.head[u]; i; i = E1.last[i])
{
int v = E1.to[i];
if(E1.f[i] && !lev[v])
{
lev[v] = lev[u] + ;
q.push(v);
}
}
if(lev[T]) return ;
}
return ;
} int dfs(int u, int nf)
{
if(u == T || !nf) return nf;
int tf = ;
for(int i = E1.head[u]; i; i = E1.last[i])
{
int v = E1.to[i];
if(!E1.f[i] || lev[v] != lev[u] + ) continue;
int af = dfs(v, min(E1.f[i], nf));
tf += af, nf -= af;
E1.f[i] -= af, E1.f[i ^ ] += af;
}
return tf;
} int dinic()
{
int nf = ;
while(bfs()) nf += dfs(S, INF);
return nf;
} void dfs2(int u)
{
for(int i = E1.head[u]; i; i = E1.last[i])
{
int v = E1.to[i]; if(!E1.f[i ^ ]) continue;
if(u > m && u <= tot + m && v >= && v <= m)
for(int j = ; j <= E1.f[i ^ ]; j ++)
{
int t = u - m; t = (id[t].u == v) ? id[t].v : id[t].u;
printf("%d %d\n", num[t], cur[v] ++);
}
if(u == S) dfs2(v);
}
} void Search(int now)
{
if(now >= m - )
{
int t = ;
for(int i = ; i <= m; i ++) d[i] = deg[i];
for(int i = ; i <= m; i ++) if(!d[i]) q.push(i);
memset(mark, , sizeof(mark));
while(!q.empty() && t <= m - )
{
int u = q.top(); q.pop();
int x = u, y = Q[t]; if(x > y) swap(x, y);
mark[x][y] = ; d[Q[t]] --;
if(!d[Q[t]]) q.push(Q[t]); t ++;
}
if(q.size() >= )
{
int x = q.top(); q.pop(); int y = q.top(); q.pop();
mark[x][y] = ;
}else if(q.size() >= ) q.pop();
for(int i = ; i < E1.cnp; i ++) E1.f[i] = E1.F[i];
for(int i = E1.head[S]; i; i = E1.last[i])
{
int v = E1.to[i]; if(!v) continue; v -= m;
int x = id[v].u, y = id[v].v;
if(x > y) swap(x, y);
E1.f[i] -= mark[x][y];
if(E1.f[i] < ) return;
}
if(dinic() == n - m)
{
for(int i = ; i <= m; i ++)
for(int j = i + ; j <= m; j ++)
if(mark[i][j]) printf("%d %d\n", num[i], num[j]);
for(int i = ; i <= m; i ++) cur[i] ++;
dfs2(S);
exit();
}
return;
}
for(int i = ; i <= m; i ++)
deg[i] ++, Q[now] = i, Search(now + ), deg[i] --;
} int main()
{
n = read(); int t = n;
while(t) { m ++; t /= ; }
for(int i = , l = ; i <= m; l *= , i ++) num[i] = cur[i] = l;
for(int i = , l = ; i < m; l *= , i ++) cal[i] = l * - num[i];
cal[m] = n - num[m] + ; S = , T = m * m + m + ;
for(int i = ; i < n; i ++)
{
scanf("%s%s", s1 + , s2 + );
int l1 = strlen(s1 + ), l2 = strlen(s2 + );
if(l1 > l2) swap(l1, l2); rec[l1][l2] ++;
}
for(int i = ; i <= m; i ++)
for(int j = i; j <= m; j ++)
{
id[++ tot].u = i, id[tot].v = j;
E1.add(S, tot + m, rec[i][j]);
E1.add(tot + m, i, INF); E1.add(tot + m, j, INF);
}
for(int i = ; i <= m; i ++) E1.add(i, T, cal[i] - );
Search();
printf("-1\n");
return ;
}

【题解】CF#611 H-New Year and Forgotten Tree的更多相关文章

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

    [题解]CF611H New Year and Forgotten Tree 神题了... 题目描述 给定你一棵树,可是每个节点上的编号看不清了,只能辨别它的长度.现在用问号的个数代表每个节点编号那个 ...

  2. CF 1045 H. Self-exploration 解题报告

    CF 1045 H. Self-exploration 考虑到串的结构一定是 1...0....1....0.....1... 这样的,而\(01\)与\(10\)在转折点交替出现 首先串长一定是\( ...

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

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

  5. 【CodeForces】914 H. Ember and Storm's Tree Game 动态规划+排列组合

    [题目]H. Ember and Storm's Tree Game [题意]Zsnuoの博客 [算法]动态规划+排列组合 [题解]题目本身其实并不难,但是大量干扰因素让题目显得很神秘. 参考:Zsn ...

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

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

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

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

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

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

随机推荐

  1. Codeception (安装)

    来源:http://codeception.com/install 注意:打开Codeception的官网需要FQ 1. 下载 下载地址:http://codeception.com/thanks 或 ...

  2. dsp6657的helloworld例程测试-第二篇-CFG文件

    1. 上一篇疑问,int StackTest()这个函数是怎么运行的,后来在.cfg文件找到了答案,.cfg包含丰富的信息,对于用惯C语言的,确实不太习惯 var Memory = xdc.useMo ...

  3. javaweb(十四)——JSP原理

    一.什么是JSP? JSP全称是Java Server Pages,它和servle技术一样,都是SUN公司定义的一种用于开发动态web资源的技术. JSP这门技术的最大的特点在于,写jsp就像在写h ...

  4. appium自动化环境搭建

    1.java开发环境JDK 2.android SDK(platform/platform tools/tools/build tools) 3.python下载安装(pip) 4.appium下载安 ...

  5. oracle数据库之组函数

    组函数也叫聚合函数,用来对一组值进行运算,并且可以返回单个值 常见的组函数: (1)count(*),count(列名)  统计行数:找到所有不为 null 的数据来统计行数 (2)avg(列名)  ...

  6. python基础知识-03-字符串

    python其他知识目录 1.for循环遍历字符串中单个字符 s_str="mcw" for i in s_str: print(i) -----------结果: m c w 2 ...

  7. centos上搭建git服务--3

    前言:当我们想要实现几个小伙伴合作开发同一个项目,或者建立一个资源分享平台的时候,GIT就是一个很好的选择.当然,既然是一个共有平台,那么把这个平台放到个人计算机上明显是不合适的,因此就要在服务器上搭 ...

  8. WIN 7 发布项目

    本人工作都快两年了不知道web 怎么发布 今天我自己非常恼火!我就暗暗研究.希望能给新手指导 准备工作:WIN7 系统 .IIS 6.0.MVC (vs 新建mvc项目自带的项目) OK begin ...

  9. lintcode-457-经典二分查找问题

    457-经典二分查找问题 在一个排序数组中找一个数,返回该数出现的任意位置,如果不存在,返回-1 样例 给出数组 [1, 2, 2, 4, 5, 5]. 对于 target = 2, 返回 1 或者 ...

  10. WebSphere应用服务器内存泄漏探测与诊断工具选择最佳实践

    内存泄漏是比较常见的一种应用程序性能问题,一旦发生,则系统的可用内存和性能持续下降:最终将导致内存不足(OutOfMemory),系统彻底宕掉,不能响应任何请求,其危害相当严重.同时,Java堆(He ...