Codeforces Round #285 (Div. 2) C Misha and Forest

C. Misha and Forest
time limit per test
1 second
memory limit per test
256 megabytes
input
standard input
output
standard output

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.

Input

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 - 10 ≤ si < 216), separated by a space.

Output

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 - 10 ≤ 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.

Examples
input
3
2 3
1 0
1 0
output
2
1 0
2 0
input
2
1 1
1 0
output
1
0 1
Note

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個點,ID從0到n-1,給出每個點的周圍點的個數也就是該點的度,然後給出與周圍點的異或值,求出該樹的所有邊。

既然是一棵樹,那麼就肯定有葉子節點,葉子節點的度爲1,從樹的葉子節點不斷的往上推,類似於拓撲排序,找到一個點度爲1,即只有一個點與該點相連接,然後刪除這個點,再來看怎麼刪除這個點,這個點的異或值就是與這個點連接的ID,然後要刪除這個點對下一個連接點的異或值的影響,又公式可得  a=b^c,b=a^c。即再異或這個點的ID一次就刪除了這個點。最後再來優化,如果暴力就是n平方的複雜度,所有這裏用了隊列來保存度爲1的點,注意刪除的過程中會影響度,所有在出隊列的時候要加一個度的判斷。

#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<queue>
using namespace std;
#define maxn 70000
int main()
{
    int n;
    int du[maxn];
    int x[maxn];
    int use[maxn];
    int ans[maxn][2];
    queue<int> qu;
    memset(use,0,sizeof(use));
    scanf("%d",&n);
    for(int i=0;i<n;i++)
    {
        scanf("%d%d",&du[i],&x[i]);
        if(du[i]==1)
            qu.push(i);
    }
    int res=0;
    while(1)
    {
        int id=-1,i;
        while(1)                //找點
        {
            if(qu.size()==0)
                break;
            int tempid=qu.front();
            qu.pop();
            if(use[tempid]==0&&du[tempid]==1)  //度會變化
            {
                use[tempid]=1;
                id=tempid;
                break;
            }
        }
        if(id==-1)
            break;
        int nextid=x[id];              //找連接點
        x[nextid]=x[nextid]^id;        //刪點刪邊
        du[nextid]--;
        if(du[nextid]==1)
            qu.push(nextid);
        ans[res][0]=id;
        ans[res++][1]=nextid;
    }
    printf("%d\n",res);
    for(int i=0;i<res;i++)
    {
        printf("%d %d\n",ans[i][0],ans[i][1]);
    }
return 0;
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章