题意:一个森林,给出n个点(n<(1<<16)),接下来n行,第i行两个数代表与i相连的点的个数和异或和,输出这颗树
题解:首先要知道异或的性质,可以从根节点出发每一个点往上异或。。。就像拓扑排序一样
#include <bits/stdc++.h> #define ll long long #define maxn (1<<16)+1000 using namespace std; ll a[maxn], dir[maxn], b[maxn], ans1[maxn], ans2[maxn],n, m, num = 0;; queue<ll >q; int main() { cin>>m; for(ll i=0;i<m;i++) cin>>a[i]>>b[i]; for(ll i=0;i<m;i++) if(a[i] == 1)q.push(i); while(!q.empty()){ ll fi = q.front(); q.pop(); if(dir[fi] == 1||a[fi]!=1) continue; q.push(b[fi]); a[b[fi]]--; b[b[fi]] ^= fi; ans1[num] = fi; ans2[num++] = b[fi]; dir[fi] = 1; } cout<<num<<endl; for(ll i=0;i<num;i++) cout<<ans1[i]<<" "<<ans2[i]<<endl; return 0; }