Codeforces547D Mike and Fish

本文介绍了解决平面上n个点进行红蓝染色的问题,确保任意一行或一列上的红点和蓝点之差不超过1。通过两种方法实现:一种是建立图论模型,另一种是直接在x和y方向上操作并添加特定数量的边。最终通过DFS遍历完成染色。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题意:一个平面上有n个点,先要求对每个点进行红蓝染色,且满足以下条件:对于任意一横行或一竖列,上面的红点和蓝点的个数之差最多为1。题目保证有解。

题解:出题人的解法有点厉害。。但是cubelove的做法更神。。被治愈了。。

做法1:将x坐标和y坐标分别放到两个点集中。如果有点(a,b),那么x点集中的a和y点集中的b连边。然后会有一个图。每条边都代表一个点。现在问题等价于对每个边染色,使得对于两个点集中的任意一个点所连的边的两种颜色的个数之差不大于1。如果所有点的度都为偶数,那么跑一遍欧拉回路,然后对走过的边轮流染红蓝。如果有的点的度数为奇数,那么就暂时先删掉它的某条边,然后归结于子问题,将其它的点按此种方法染色好以后,再考虑当时去的边应该染什么颜色。

做法2:考虑以下性质:如果某行或某列中有k个点,那么可以对这k个点加上[k/2]条边,使得每个点最多连了一条边。此时对每条边两端染不同的颜色就解决了。如果有孤立点,任意染色。所以我们可以这样对x方向和y方向操作,然后连边。最后对每个点dfs一下,保证每条边的两边的颜色不同,答案就出来了。



被做法2治愈了。。。


#include<bits/stdc++.h>
#define pb push_back
using namespace std;
const int N=201111;
vector<int> v[N];
int t[N],a[N][2];
void dfs(int x,int y){
    if(t[x]) return ;
    t[x]=y;
    for(int i=0;i<v[x].size();i++) dfs(v[x][i],3-y);
}
int main()
{
    int i,j,n,x,y;
    scanf("%d",&n);
    for(i=1;i<=n;i++){
        for(j=0;j<2;j++){
            scanf("%d",&x);
            if(a[x][j]){
                v[i].pb(a[x][j]);
                v[a[x][j]].pb(i);
                a[x][j]=0;
            }else a[x][j]=i;
        }
    }
    for(i=1;i<=n;i++) dfs(i,1),putchar(t[i]>1?'r':'b');
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值