题解:CF2048E Kevin and Bipartite Graph
MitchellZhong · · 题解
Solution fo CF2048E
前言
这道题真的有点难发现结论,感谢 @Code937 老师给我的启发,这道题我们和其他同学讨论了不下
题意
你有一个二分图,左边有
你需要给每个边染上一种颜色,总共有
求一种构造。
解法
-
首先观察到有无解情况。
我们思考什么情况下会误解。
每一条边最多可以连到
2n+m-1 个点(总共有2n+m ,要构成一棵树 所以是上述数字)。总共有
2nm 条边,所以当所有边都被染色是充要条件是:n(2n+m-1) \ge 2nm 即:
2n+m-1 \ge 2m 即:
2n > m 所以无解的充要条件是:
2n \le m -
我们再考虑
m=2n-1 的构造方式即可(因为其他其实同理)我们来先思考
n=2 时的构造方案,如下:首先来看一种不合法的构造:
粉色部分及不合法部分,我们观察到两边同高度有红拐角,这样就会出现问题。
经过讨论后,我们发现第一次染红时如下染色即可:
让我们思考第二次可不可以这么染色:
其实显然可以,因为这让不会出现上述错误情况。
那么这么染色保证可以染完吗?
也是可以的,稍加计算可得这样做完全可以覆盖。
我们还是看图:
于是按上面模拟即可。
代码
#include <bits/stdc++.h>
// #pragma GCC optimize(3,"Ofast","inline")
namespace FastIO {
constexpr int LEN = 1 << 20;
inline char getchar() {
static char buf[LEN], *l = buf, *r = buf;
if (l == r) r = (l = buf) + fread(buf, 1, LEN, stdin);
return l == r ? EOF : *l++;
}
char obuf[LEN], *p = obuf;
inline void putchar(const char &c) {
if (p == obuf + LEN) fwrite(p = obuf, 1, LEN, stdout);
*p++ = c;
}
inline void flush() {
fwrite(obuf, 1, p - obuf, stdout);
}
struct Reader {
template<typename T> inline Reader &operator >> (T &x) {
x = 0;
short f = 1;
char c = getchar();
while (!isdigit(c)) {
if (c == '-') f = -1;
c = getchar();
}
while (isdigit(c)) x = 10 * x + (c - '0'), c = getchar();
x *= f;
return *this;
}
inline Reader &operator >> (std::string &s) {
s.clear();
char c = getchar();
while (c != EOF && c <= 32) c = getchar();
while (c > 32) {
s += c;
c = getchar();
}
return *this;
}
} cin;
struct Writer {
template<typename T> inline Writer &operator << (T x) {
if (x < 0) putchar('-'), x = -x;
static unsigned char tp = 0, s[40];
do s[++tp] = x % 10 + '0', x /= 10; while (x);
while (tp) putchar(s[tp--]);
return *this;
}
inline Writer &operator << (const char *s) {
int i = 0;
while (s[i]) putchar(s[i++]);
return *this;
}
inline Writer &operator << (const char &c) {
putchar(c);
return *this;
}
inline Writer &operator << (const std::string &s) {
return (*this) << s.c_str();
}
~Writer() {
flush();
}
} cout;
}
#define cin FastIO::cin
#define cout FastIO::cout
#define endl '\n'
// #define int long long
using namespace std;
int t;
int n;
int m;
vector<pair<int,int> > ans;
int vis[3005][3005];
signed main(){
cin>>t;
while(t--){
cin>>n>>m;
if(m>=2*n){
cout<<"No"<<endl;
continue;
}
cout<<"Yes"<<endl;
for(int i=1;i<=n;i++){
int l=i*2-1;
int r=1;
while(r<=n*2-1){
vis[l][r]=i;
if(l>=n*2){
vis[1][r]=i;
l=0;
}else{
vis[l+1][r]=i;
}
l++,r++;
}
}
for(int i=1;i<=2*n;i++){
for(int j=1;j<=m;j++){
cout<<vis[i][j]<<" ";
}
cout<<endl;
}
}
return 0;
}
完结撒花喵!