C - Misha and Forest

来源:互联网 发布:大学生网络诈骗ppt 编辑:程序博客网 时间:2024/05/22 03:27

感觉CF的题都是蛮巧妙的,题里 的每一句话都不是白给的,

 就像这道题, 他说图里没有环, 就说明了两点, 1  -> 一定有度为一的节点     2->所有度的和一定是偶数, 确sum/2就等于变数

  然后我们可以从 度为1 的节点入手。 它的sv一定是他临近节点的序号, 通过这个我们可以慢慢把所有节点的边都找出来

#include <iostream>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <queue>


using namespace std;
#define MAXN 111111
#define LL long long
struct node
{
    int id, deg, s;
}sta[MAXN];
queue<node> que;
int main()
{
    int n;
    scanf("%d",&n);
    LL sum = 0;


    for(int i = 0 ; i < n ; i++)
    {
        sta[i].id = i;
        scanf("%d %d",&sta[i].deg, &sta[i].s);
        if(sta[i].deg == 1)
          que.push(sta[i]);
        sum += (LL)sta[i].deg;
    }
    printf("%d\n",sum/2);
    while(!que.empty())
    {
        node tem = que.front();
        que.pop();

//这里要注意不能写成tem.deg因为队列里的元素的度是没更改之前的度, 我们要看的是更改之后的这时

//sta[i].id映射就发挥作用了
        if(sta[tem.id].deg != 1)
          continue;

        printf("%d %d\n",tem.id, tem.s);

//x^x = 0 ,0^x = x 所以这一步相当于把当前节点对其临近节点的影响删除
        sta[tem.s].s ^= tem.id;
        if(--sta[tem.s].deg == 1)
          que.push(sta[tem.s]);


    }
    return 0;
}0;
}

0 0
原创粉丝点击