牛客OI周赛1-提高组 A-分组

版权声明:喜欢请点个大拇指,感谢各位dalao。弱弱说下,转载要出处呦 https://blog.csdn.net/qq_35786326/article/details/82949559


题目:

传送门


分析:

看到题目 b b bb 一堆,这里我们转换下:

在有n个节点的图中,每个节点的度数不超过3,现在要我们对其进行黑白染色,使得相邻节点中只出现至多2个相同颜色的节点

现在我们很容易想到用二分图做,但本蒟蒻不会呀,可仍然有更优更简单的方法:用 d f s dfs 来进行黑白染色
怎么讲呢,我们通过 d f s dfs 不断更正我们的答案
首先对于当前节点 ( n o w ) (now) 的字节点 ( u ) (u) ,当 u u 没有答案时,我们将以 n o w now 的答案取反填入,再以 u u 进行 d f s dfs
可显然,会在这个过程中出现多个相同颜色的节点,那么我们可以考虑在 d f s dfs 求出子节点的答案后统计与 n o w now 相同颜色的节点数,遍历完所有子节点后,当统计的数 > 1 >1 (即有多个相同颜色的节点),我们就可以直接将 n o w now 的答案取反
至此,本题就基本结束了


代码:

#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring> 
#include<cstdlib>
#include<algorithm>
#include<set>
#include<queue>
#include<vector>
#include<map>
#include<list>
#include<ctime>
#include<iomanip>
#include<string>
#include<bitset>
#include<deque>
#include<set>
#define LL long long
#define ch cheap
#define XJQ (int)1000000007
using namespace std;
inline LL read() {
    LL d=0,f=1;char s=getchar();
    while(s<'0'||s>'9'){if(s=='-')f=-1;s=getchar();}
    while(s>='0'&&s<='9'){d=d*10+s-'0';s=getchar();}
    return d*f;
}
struct node{
    int t,n;
}t[300005];
int ls[300005],cnt=0;
int ans[(int)1e5+5];
void dfs(int now)
{
    int sum=0;
    for(int i=ls[now];~i;i=t[i].n)
    {
        int u=t[i].t;
        if(!ans[u]) ans[u]=ans[now]^3,dfs(u);
        if(ans[now]==ans[u]) sum++;
    }
    if(sum>1) ans[now]^=3;
    return;
}
int main()
{
    int n=read(),m=read();
    memset(ls,-1,sizeof(ls));
    for(int i=1;i<=m;i++)
    {
        int x=read(),y=read();
        t[cnt]=(node){y,ls[x]};ls[x]=cnt++;
        t[cnt]=(node){x,ls[y]};ls[y]=cnt++;
    }
    for(int i=1;i<=n;i++)
    {
        if(!ans[i]) ans[i]=1,dfs(i);
        printf("%d ",ans[i]);
    }
    return 0;
}

玄中之玄:

用该种算法,是不能做到 A C AC 题目样例的,但因为有 S p e c i a l Special J u d i n g Juding ,所以还是可以 A A

猜你喜欢

转载自blog.csdn.net/qq_35786326/article/details/82949559