题意:
定义一个森林是一个无向无环的图,给你n个顶点(从0 - n-1)。对于每一个顶点有输入两个值,一个表示顶点的度数,一个表示与该顶点按位异或的和。(没有,就记住0)。现在要你根据这个条件把图复原出来。
思路:
对于叶子来说,只有一条边与他相连,把这条边打印,然后去掉,继续寻找叶子,直到结束。
如果一个数异或另外一个数两次,那么就变成了这个数本身。利用这个特点,将每个叶子的影响去掉。
#include <map> #include <set> #include <cstdio> #include <cstring> #include <algorithm> #include <queue> #include <iostream> #include <stack> #include <cmath> #include <string> #include <vector> #include <cstdlib> //#include <bits/stdc++.h> //#define LOACL #define space " " using namespace std; //typedef long long LL; //typedef __int64 Int; typedef pair<int, int> PAI; const int INF = 0x3f3f3f3f; const double ESP = 1e-5; const double PI = acos(-1.0); const int MOD = 1e9 + 7; const int MAXN = (1 << 16) + 10; PAI data[MAXN]; int main() { int n; while (scanf("%d", &n) != EOF) { queue <int> que; for (int i = 0; i < n; i++) { scanf("%d%d", &data[i].first, &data[i].second); if (data[i].first == 1) que.push(i); } PAI ans[MAXN]; int cnt = 0; while (que.size()) { int u = que.front(); que.pop(); if (data[u].first != 1) continue; int v = data[u].second; data[u].first = 0; ans[cnt].first = u, ans[cnt++].second = v; data[v].second ^= u; data[v].first--; if (data[v].first == 1) { que.push(v); } } printf("%d ", cnt); for (int i = 0; i < cnt; i++) { printf("%d %d ", ans[i].first, ans[i].second); } } return 0; }