C. Misha and Forest

 

Let's define a forest as a non-directed acyclic graph (also without loops and parallel edges). One day Misha played with the forest consisting of n vertices. For each vertex v from 0 to n - 1 he wrote down two integers, degreev and sv, were the first integer is the number of vertices adjacent to vertex v, and the second integer is the XOR sum of the numbers of vertices adjacent to v (if there were no adjacent vertices, he wrote down 0).

Next day Misha couldn't remember what graph he initially had. Misha has values degreev and sv left, though. Help him find the number of edges and the edges of the initial graph. It is guaranteed that there exists a forest that corresponds to the numbers written by Misha.

Input

The first line contains integer n (1 ≤ n ≤ 216), the number of vertices in the graph.

The i-th of the next lines contains numbers degreei and si (0 ≤ degreei ≤ n - 1, 0 ≤ si < 216), separated by a space.

Output

In the first line print number m, the number of edges of the graph.

Next print m lines, each containing two distinct numbers, a and b (0 ≤ a ≤ n - 1, 0 ≤ b ≤ n - 1), corresponding to edge(a, b).

Edges can be printed in any order; vertices of the edge can also be printed in any order.

Sample test(s)
input
3
2 3
1 0
1 0
output
2
1 0
2 0
input
2
1 1
1 0
output
1
0 1
Note

The XOR sum of numbers is the result of bitwise adding numbers modulo 2. This operation exists in many modern programming languages. For example, in languages C++, Java and Python it is represented as "^", and in Pascal — as "xor".

题意:

有一个森林,若干棵树,一共有n个节点,编号为0~n-1,现在对于每一个节点,给出degi,sumi

degi表示节点i的度(入度+出度)

sumi表示所有和节点i直接相连的节点的编号的xor和

输出边的数量和所有边的2个端点

(e=(u,v),则输出u v)

思路:

突破口:当节点i为叶子节点时,只有一个入度,没有出度,则degi=1,这个时候fa[i]=sumi

这个时候和fa[i]相连的边确定了1条了,则:

deg[fa[i]]--

sum[fa[i]]=change(i,sum[fa[i]])

函数change(int b,int c)的功能:

有方程式x^b=c,现在我们知道了b,c,这个函数的返回值是x

那么当deg[fa[i]]==1的时候,就说明节点fa[i]还剩下1条边没有确定,而这条边的另一个顶点就是此时的sum[fa[i]]

则fa[fa[i]]=sum[fa[i]]

对于每一个节点,degi=0时说明没有边与之相连,不用管它

degi>0,就总会有degi=1的时候,这个时候,节点i的父亲节点就确定了

但是这样有一个问题:

对于根节点root是没有父亲节点的,但是会有deg[root]==1的时刻,按照上面的想法这个时候我们给了root一个父亲节点,而实际上, 我们不应该给root这个父亲节点

所以:对于节点i,满足2个条件,才可以确定父亲节点

1.deg[i]==1

2.fa[i.sum]==-1(为了防止给root父亲节点)

 #include<cstdio>
#include<cstring>
#include<queue> using namespace std; const int maxn=(<<)+; int fa[maxn];
struct Node
{
int deg,sum,cnt;
};
Node node[maxn]; inline int change(int b,int c)
{
int ret=;
int i=;
while(b>||c>)
{
if((b&)!=(c&))
{
ret+=(<<i);
}
b>>=;
c>>=;
i++;
}
return ret;
} void solve(int ); int main()
{
int n;
scanf("%d",&n);
int tmp=;
for(int i=;i<n;i++)
{
scanf("%d %d",&node[i].deg,&node[i].sum);
tmp+=node[i].deg;
node[i].cnt=i;
}
printf("%d\n",tmp/);
solve(n); return ;
} void solve(int n)
{
memset(fa,-,sizeof fa);
queue<Node>que;
while(!que.empty())
que.pop();
for(int i=;i<n;i++)
{
if(node[i].deg==)
que.push(node[i]);
}
while(!que.empty())
{
Node u=que.front();
que.pop();
if(fa[u.sum]<)
fa[u.cnt]=u.sum;
int j=fa[u.cnt];
node[j].deg--;
node[j].sum=change(u.cnt,node[j].sum);
if(node[j].deg==)
que.push(node[j]);
}
for(int i=;i<n;i++)
{
if(fa[i]!=-)
{
printf("%d %d\n",i,fa[i]);
}
}
return ;
}

CF 501C Misha and Forest 好题的更多相关文章

  1. codeforces 501C. Misha and Forest 解题报告

    题目链接:http://codeforces.com/problemset/problem/501/C 题目意思:有 n 个点,编号为 0 - n-1.给出 n 个点的度数(即有多少个点跟它有边相连) ...

  2. 水题 Codeforces Round #285 (Div. 2) C. Misha and Forest

    题目传送门 /* 题意:给出无向无环图,每一个点的度数和相邻点的异或和(a^b^c^....) 图论/位运算:其实这题很简单.类似拓扑排序,先把度数为1的先入对,每一次少一个度数 关键在于更新异或和, ...

  3. 图论/位运算 Codeforces Round #285 (Div. 2) C. Misha and Forest

    题目传送门 /* 题意:给出无向无环图,每一个点的度数和相邻点的异或和(a^b^c^....) 图论/位运算:其实这题很简单.类似拓扑排序,先把度数为1的先入对,每一次少一个度数 关键在于更新异或和, ...

  4. Codeforces Round #285 (Div. 1) A. Misha and Forest 拓扑排序

    题目链接: 题目 A. Misha and Forest time limit per test 1 second memory limit per test 256 megabytes 问题描述 L ...

  5. CF上的3道小题(2)

    CF上的3道小题(2) T1:CF630K Indivisibility 题意:给出一个数n,求1到n的数中不能被2到9中任意一个数整除的数. 分析:容斥一下,没了. 代码: #include < ...

  6. CF上的3道小题(1)

    CF上的3道小题 终于调完了啊.... T1:CF702E Analysis of Pathes in Functional Graph 题意:你获得了一个n个点有向图,每个点只有一条出边.第i个点的 ...

  7. 清橙A1206.小Z的袜子 && CF 86D(莫队两题)

    清橙A1206.小Z的袜子 && CF 86D(莫队两题) 在网上看了一些别人写的关于莫队算法的介绍,我认为,莫队与其说是一种算法,不如说是一种思想,他通过先分块再排序来优化离线查询问 ...

  8. 【Codeforces 501C】Misha and Forest

    [链接] 我是链接,点我呀:) [题意] 给你一棵树 但是每个节点只告诉你出度个数 以及所有和它相连的点的异或和. 让你还原这棵树 [题解] 叶子节点的话,他所有节点的异或和就是它那唯一的一个爸爸 因 ...

  9. Codeforces Round #285 (Div. 2)C. Misha and Forest(拓扑排序)

    传送门 Description Let's define a forest as a non-directed acyclic graph (also without loops and parall ...

随机推荐

  1. HDU-3586 Information Disturbing(树形DP+删边)

    题目大意:一棵有n个节点的有根树,1为根节点,边带权,表示删掉这条边的代价.现在要删掉一些边,使叶子节点不能到达根节点.但是,每次删除的边的代价不能超过limit,删掉的边的总代价不能超过m,求最小的 ...

  2. Java Language and Virtual Machine Specifications

    The Java Language Specification, Java SE 8 Edition HTML | PDF The Java Virtual Machine Specification ...

  3. DNS与DSN

    dns是域名系统的缩写 dsn在一些专业书籍中是数据源的缩写

  4. 让边框和文本一样高,不受line-height影响,可以使用padding,padding可以用于行内元素

    如果设置了,display:inline-block;边框大小至少和行高一样.这样就可能比文字高.

  5. noip2013提高组day1第一题-转圈游戏——快速幂典型应用

    所谓的快速幂: // 计算 m^n % k 的快速幂算法 int quickpow(int m,int n,int k) { ; ) { ) b = (b*m)%k; n = n >> ; ...

  6. CentOS 6使用mutt+msmtp发送邮件

    转:http://www.tuicool.com/articles/YRnQVfq CentOS系统下如果希望向外域发送邮件,需要配置sendmail+dovecot等一系列工具.其实不用这么麻烦,只 ...

  7. python3多线程趣味详解

    python3的多线程很多人无法理解是怎么运行的,因此本文从程序猿的日常生活出发,写了一个由浅入深的多线程教程,这样子大家就不会觉得陌生了,多线程真的很简单很简单! 不要讲多线程局限于库或者框架,自己 ...

  8. Zabbix 教程

    Zabbix 教程http://blog.csdn.net/linuxlsq/article/details/52606086 MySQL在以下几种情况会创建临时表:1.UNION查询:2.用到TEM ...

  9. linux shell 整理收集(不断更新)

    1)主从复制延时判断 (转 http://www.cnblogs.com/gomysql/p/3862018.html) 说明: 不要通过Seconds_Behind_Master去判断,该值表示sl ...

  10. smarty函数-继承extents

    继承<{extends}> {extends}标签用在模版中的第一行: 如果子模板用{extends}标签继承父模板,那么它只能包含{block}标签(内容),其它任何模板内容都将忽略: ...