题意:n个点组成的森林,n<=6e4,给出n个点度数和s[v]:与v相邻点的异或值,求出森林的边
若v的degree为1,则有边v->s[v],按照拓扑序遍历树,依次更新出边即可
#include <bits/stdc++.h>
using namespace std;
typedef pair<int,int> ii;
const int N=2e5+20;
int n,d[N],s[N],vis[N];
queue<int> q;
vector<ii> ans;
void Topo()
{
memset(vis,0,sizeof(vis));
for(int i=0;i<n;i++)
{
if(d[i]==1)
q.push(i),vis[i]=1;
}
while(!q.empty())
{
int u=q.front();
q.pop();
//d[u]若为0 则u->s[u]的边已经添加
if(d[u]==0)
continue;
ans.push_back(ii(u,s[u]));
d[s[u]]--;
s[s[u]]^=u;//删除点u后,更新结点s[u]
if(vis[s[u]]==0&&d[s[u]]==1)
q.push(s[u]),vis[s[u]]=1;
}
}
int main()
{
while(cin>>n)
{
ans.clear();
for(int i=0;i<n;i++)
scanf("%d%d",&d[i],&s[i]);
Topo();
cout<<ans.size()<<endl;
for(int i=0;i<ans.size();i++)
cout<<ans[i].first<<' '<<ans[i].second<<endl;
}
return 0;
}