循环流 [构造题]

循环流



\color{red}{正解部分}

分类讨论, 设 1,21,2 边 的数量分别为 cnt1,cnt2cnt_1, cnt_2,

  • N=2N=2, cnt1cnt_1 必须为偶数; 当 cnt1=0cnt_1=0 时, cnt2cnt_2 不为奇数 .
  • N>2N>2, 首先讨论 cnt1cnt_1cnt2cnt_2 都不为 00 的情况, 有解的条件是 cnt1+cnt2N+1cnt_1 + cnt_2 \geq N+1 .

N>2N>2时, 将 11边 和 22边 各构成一个环, 控制 所有11边 都在 第一个环 里,
第二个环若无法被 22边 完整地填充, 则通过下图的方式联通两环,

否则只需要将两个点看成一个点, 合起来即可, 从 N+1N+1个点 变成了 NN 个点 .


  • 再讨论其中一种边个数为 00 的情况, 只需要边的条数 大于等于 NN 即可, 若出现了剩余的边, 这么连就可以了 .

  • cnt1cnt_1 不能等于 11, 但是 cnt2cnt_2 可以等于 11, 此时只需要将一个 11边 反向, 22边 正向, 相减后与不加 22 边没有区别 .

\color{red}{实现部分}

#include<bits/stdc++.h>
#define reg register

const int maxn = 55;

int read(){
        char c;
        int s = 0, flag = 1;
        while((c=getchar()) && !isdigit(c))
                if(c == '-'){ flag = -1, c = getchar(); break ; }
        while(isdigit(c)) s = s*10 + c-'0', c = getchar();
        return s * flag;
}

int N;
int a;
int b;

void Sc(){
        N = read(), a = read(), b = read();
        if(a == 1){ puts("0"); return ; }
        if(N == 2){
                if(a & 1) puts("0");
                else if(!a && (b&1)) puts("0");
                else if(a+b < N) puts("0");
                else puts("1");
                return ;
        }else{
                if((!a || !b) && (a+b >= N)) puts("1");
                else if(a && b && a+b >= N+1) puts("1");
                else puts("0");
        }
}

int main(){
        read();
        int T = read(); while(T --) Sc();
        return 0;
}
posted @ 2019-09-24 17:22  XXX_Zbr  阅读(136)  评论(0编辑  收藏  举报