期末复习各种事 好久没做题了… 还好有ChineseRound
题意:
n(2^16)个点组成的森林 给出每个点的度以及相邻点的异或和 求 输出所有边
思路:
因为是森林 所以最多n-1条边 那么我们直接从叶子开始bfs 因为叶子度为1 它的所记录的异或和就是旁边的点
复杂度O(n) 唯一需要注意的就是以d[u]==1进入队列的点不一定有边要输出 例如 1-2 这棵树 1和2都会进队列 但只有1条边
代码:
#include<cstdio>
#include<iostream>
#include<cstring>
#include<string>
#include<algorithm>
#include<map>
#include<set>
#include<vector>
#include<queue>
#include<cstdlib>
#include<ctime>
#include<cmath>
using namespace std;
typedef long long LL;
#define N 70000
int n;
int d[N], f[N];
int q[N], l, r;
struct edge {
int u, v;
} ed[N];
int tot;
void add(int u, int v) {
ed[tot].u = u;
ed[tot].v = v;
tot++;
}
int main() {
scanf("%d", &n);
for (int i = 0; i < n; i++) {
scanf("%d%d", &d[i], &f[i]);
if (d[i] == 1) q[r++] = i;
}
while (l < r) {
int u = q[l++];
if (d[u] == 1) {
add(u, f[u]);
d[u]--;
d[f[u]]--;
f[f[u]] ^= u;
if (d[f[u]] == 1) q[r++] = f[u];
}
}
printf("%d\n", tot);
for (int i = 0; i < tot; i++) printf("%d %d\n", ed[i].u, ed[i].v);
return 0;
}