CF547D Mike and Fish

CF547D Mike and Fish

这也能图论的一道题。

思路

对于 x 坐标相同的点,我们两两配对连边,多余的点不管。

对于 y 坐标相同的点,我们两两配对连边,多余的点不管。

这样就得到了若干个连通图,对这些连通图跑二分图染色即可得到答案。

证明:

由于是二分图染色,且横竖两两配对,由于连了边的点都不可能是相同的颜色,所以横竖都可以保证最少有 n2 个点染成了一个颜色。

如果二分图染色不成功怎么办?

由于每个点最多两条边,所以说想要染色不成功只有可能是形成了奇数环。

这两条边一条横着一条竖着,我们不妨先加入环上所有的横边,设有 x 条。

这时形成了 x 个连通块,这些连通块想要形成环就必须添加 x 条竖边。

那么总边数就是 2x 条。

由于环上点数等于环边数,所以有 2x 个点,故得证不会有奇数环。

CODE

#include<bits/stdc++.h>
using namespace std;

const int maxn=2e5+5;

vector<int>E[maxn];

int col[maxn];

int lsth[maxn],lstw[maxn];

int n;

inline void dfs(int u,int tw)
{
    col[u]=tw;
    for(auto v:E[u]) if(col[v]==-1) dfs(v,tw^1);
}

int main()
{
    scanf("%d",&n);
    for(int i=1;i<=n;i++)
    {
        int x,y;col[i]=-1;
        scanf("%d%d",&x,&y);
        if(lsth[x]){E[i].push_back(lsth[x]);E[lsth[x]].push_back(i);lsth[x]=0;}else lsth[x]=i;
        if(lstw[y]){E[i].push_back(lstw[y]);E[lstw[y]].push_back(i);lstw[y]=0;}else lstw[y]=i;
    }
    for(int i=1;i<=n;i++) if(col[i]==-1) dfs(i,0);
    for(int i=1;i<=n;i++) if(col[i]) putchar('r');else putchar('b');
}

题解 from:shadowice1984 题解 CF547D 【Mike and Fish】

posted @   彬彬冰激凌  阅读(23)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· 三行代码完成国际化适配,妙~啊~
· .NET Core 中如何实现缓存的预热?
· 如何调用 DeepSeek 的自然语言处理 API 接口并集成到在线客服系统
点击右上角即可分享
微信分享提示