CF 501C Misha and Forest 好题
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.
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.
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.
3
2 3
1 0
1 0
2
1 0
2 0
2
1 1
1 0
1
0 1
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 好题的更多相关文章
- codeforces 501C. Misha and Forest 解题报告
题目链接:http://codeforces.com/problemset/problem/501/C 题目意思:有 n 个点,编号为 0 - n-1.给出 n 个点的度数(即有多少个点跟它有边相连) ...
- 水题 Codeforces Round #285 (Div. 2) C. Misha and Forest
题目传送门 /* 题意:给出无向无环图,每一个点的度数和相邻点的异或和(a^b^c^....) 图论/位运算:其实这题很简单.类似拓扑排序,先把度数为1的先入对,每一次少一个度数 关键在于更新异或和, ...
- 图论/位运算 Codeforces Round #285 (Div. 2) C. Misha and Forest
题目传送门 /* 题意:给出无向无环图,每一个点的度数和相邻点的异或和(a^b^c^....) 图论/位运算:其实这题很简单.类似拓扑排序,先把度数为1的先入对,每一次少一个度数 关键在于更新异或和, ...
- 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 ...
- CF上的3道小题(2)
CF上的3道小题(2) T1:CF630K Indivisibility 题意:给出一个数n,求1到n的数中不能被2到9中任意一个数整除的数. 分析:容斥一下,没了. 代码: #include < ...
- CF上的3道小题(1)
CF上的3道小题 终于调完了啊.... T1:CF702E Analysis of Pathes in Functional Graph 题意:你获得了一个n个点有向图,每个点只有一条出边.第i个点的 ...
- 清橙A1206.小Z的袜子 && CF 86D(莫队两题)
清橙A1206.小Z的袜子 && CF 86D(莫队两题) 在网上看了一些别人写的关于莫队算法的介绍,我认为,莫队与其说是一种算法,不如说是一种思想,他通过先分块再排序来优化离线查询问 ...
- 【Codeforces 501C】Misha and Forest
[链接] 我是链接,点我呀:) [题意] 给你一棵树 但是每个节点只告诉你出度个数 以及所有和它相连的点的异或和. 让你还原这棵树 [题解] 叶子节点的话,他所有节点的异或和就是它那唯一的一个爸爸 因 ...
- 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 ...
随机推荐
- scala言语基础学习六
trait的学习 1.将trait作为接口来使用 trait中可以实现一些方法,子类只要extends 了trait就可以直接使用父trait里面的方法 普通继承的话父类和子类之间的field是通过引 ...
- phpmyadmin导入导出大数据文件的办法
在phpmyadmin的使用中,经常需要进行导入导出数据库的操作. 但是在导入导出大型数据库文件的时候经常会只是部分导出或者部分导入. 或者是导入导出不成功. 原因就是服务器和php.mysql限制了 ...
- List of devices attached ???????????? no permissions
如果显示如下:List of devices attached???????????? no permissions就要设置usb $ lsusbBus 005 Device 001: ID 1d6b ...
- Vi个人学习使用心得
找句首/句末 光标所在行:句首: shift+^; 句末: shift +$; 括号匹配:光标在某一括号上,然后shift+% 快速对齐 针对括号的内容:将括号中的内容全部选中之后(按V后, shif ...
- (译) 强化学习 第一部分:Q-Learning 以及相关探索
(译) 强化学习 第一部分:Q-Learning 以及相关探索 Q-Learning review: Q-Learning 的基础要点是:有一个关于环境状态S的表达式,这些状态中可能的动作 a,然后你 ...
- git checkout 和 git checkout --merge <branch_name>使用
一.git checkout //查看当前分支$ git branch master *t2 testing //checkout会覆盖当前工作区文件和覆盖暂存区内容,所以发现分支有未提交的警告,执行 ...
- unity3d中Find的用法
在unity3d中用Find可以直接查找组件 例子一: 该脚本时绑在main Camera上的,"/Scene/player"这是在Hierarchy目录下直接找寻Scene ...
- SQL Server 索引分类
什么是索引 拿汉语字典的目录页(索引)打比方:正如汉语字典中的汉字按页存放一样,SQL Server中的数据记录也是按页存放的,每页容量一般为4K .为了加快查找的速度,汉语字(词)典一般都有按拼音. ...
- OpenJudge计算概论-点和正方形的关系【判断点是否在正方形内部】
/*======================================================== 点和正方形的关系 总时间限制: 1000ms 内存限制: 65536kB 描述 有 ...
- lambda 的使用汇总
d=lambda x:x+1print(d(10))lambda 相当于一个轻量函数返回 d=lambda x:x+1 if x>0 else "error"print(d( ...