循环流(图论相关知识)
题目描述
你学习了网络流的相关知识,现在你要大显神通……
你曾经有一个循环流(每个点均满足流量平衡条件),这个流网络上有n个点,且每条边的流量只有1或2,可能有重边却没有自环。显然,由于它是一个流网络,它是一个弱连通图(将边视为无向边后为连通图)。遗憾的是你找不到这个流了,但你曾经记下了它流量为111的边的数量和流量为2的边的数量。由于这个图的点数有点多,你很有可能数错边数,因此你现在想知道存不存在这样一个流符合你记下的数据。
输入
第一行一个整数表示数据所属的测试点编号,其具体含义见测试点约束(若为0表示样例数据);
第二行一个整数T表示数据组数;
接下来T行每行三个整数n,a,b,分别表示点数,流量为1的边的数量和流量为2的边的数量。
第二行一个整数T表示数据组数;
接下来T行每行三个整数n,a,b,分别表示点数,流量为1的边的数量和流量为2的边的数量。
输出
输出T行,每行一个为0或1的整数,1表示存在一个合法流,0表示不存在。
样例输入 Copy
0
3
2 2 1
4 2 3
5 2 3
样例输出 Copy
1
1
0
提示
对于所有的测试数据,保证:2≤n≤50,0≤a,b≤50,1≤T≤127449
思路:一开始以为不好做的,其实就是构造。当n==2,显然可以特判。当其中a或者b为0,必须a>=n||b>=n。此时可以构造欧拉回路,然后再中间加重边。
其他情况,显然a==1时,不可能。a+b<n不可能。因为a,b都存在的话,先构造b,从1到x连一条链,然后x接到1,此时可以把这x个点看作两个点1——2,然后剩下的点照着情况1就可以。发现a+b-1>=n才可以。
#pragma comment(linker, "/STACK:1024000000,1024000000")
#pragma GCC optimize(3,"Ofast","inline")
#include <bits/stdc++.h>
using namespace std;
#define rep(i , a , b) for(register ll i=(a);i<=(b);i++)
#define per(i , a , b) for(register ll i=(a);i>=(b);i--)
#define ms(s) memset(s, 0, sizeof(s))
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int , int> pi;
typedef unordered_map<int,int> un_map;
template<class T>
inline void read (T &x) {
x = 0;
int sign = 1;
char c = getchar ();
while (c < '0' || c > '9') {
if ( c == '-' ) sign = - 1;
c = getchar ();
}
while (c >= '0' && c <= '9') {
x = x * 10 + c - '0';
c = getchar ();
}
x = x * sign;
}
const int maxn = 5e5+10;
const int inf = 0x3f3f3f3f;
const ll INF = ll(1e18);
const ll mod = 1011110011;
const double PI = acos(-1);
bool check(ll n,ll a,ll b) {
if(a==1) return false;
if(a+b<n) return false;
if(n==2) {
if(a%2==1) return false;
else if(a==0&&b%2==1) return false;
else return true;
}
if(a+b==n) {
if(a==0||b==0) return true;
return false;
}
if(a+b>=n+1) return true;
return false;
}
int main(int argc, char * argv[])
{
int o;
read(o);
int _t;
read(_t);
while(_t--) {
ll n,a,b;
read(n);read(a);read(b);
if(check(n,a,b)) puts("1");
else puts("0");
}
return 0;
}