F. Strange Housing(思维,图论)

F. Strange Housing

题目传送门:

F. Strange Housing

题目大意:

对于图中的n个点进行染色,一条边的两端不能同时染色。染色之后端点有染色的边会保留下来,要求染色之后的图连通。

思路:

1.显然当图连通时一定存在答案,否则不存在。
2.bfs遍历所有点:
如果当前节点没有染色,且相邻的所有点都没有染色,就染色,否则不染色。
如果当前节点已经染色,那么相邻的所有节点都不染色。
证明:显然这种方案不会存在一条边两个端点都染色的情况。其次,如果图不连通,一定是有一个点连接的所有点都不染色,而这样的点一定会存在第一种情况下被染色,所以图一定是连通的。

#include<bits/stdc++.h>
using namespace std;
const int N=6e5+10;
int head[N];
struct node
{
    
    
    int to,next;
}tr[N];
int cent=0;
int n,m;
void add(int u,int v)
{
    
    
    tr[cent].to=v;
    tr[cent].next=head[u];
    head[u]=cent++;
}
int ans[N],f[N];
int res=0;
bool bfs()//检查图是否连通
{
    
    
    for(int i=0;i<=n+10;i++)//标记有没有遍历到过
        ans[i]=0;
    ans[1]=1;
    queue<int>que;
    que.push(1);
    int num=1;
    while(!que.empty())
    {
    
    
        int now=que.front();
        que.pop();
        for(int i=head[now];~i;i=tr[i].next)
        {
    
    
            int to=tr[i].to;
            if(ans[to]==0)
            {
    
    
                ans[to]=1;
                que.push(to);
                num++;
            }
        }
    }
    if(num==n) return true;
    else return false;
}
void solve()
{
    
    
    for(int i=0;i<=n+10;i++)
    {
    
    
        ans[i]=0;
        f[i]=0;
    }
    f[1]=1;
    queue<int>que;
    que.push(1);
    while(!que.empty())
    {
    
    
        int now=que.front();
        que.pop();
        int flag=0;
        for(int i=head[now];~i;i=tr[i].next)
        {
    
    
            int to=tr[i].to;
            if(ans[to]==1)
                flag=1;
            if(f[to]==0)
            {
    
    
                f[to]=1;
                que.push(to);
            }
        }
        if(flag==0)
        {
    
    
            ans[now]=1;
            res++;
        } 
    }
}
int main()
{
    
    
    int t;
    scanf("%d",&t);
    while(t--)
    {
    
    
        scanf("%d%d",&n,&m);
        for(int i=0;i<=n+10;i++) head[i]=-1;
        cent=0;
        res=0;
        for(int i=1;i<=m;i++)
        {
    
    
            int u,v;
            scanf("%d%d",&u,&v);
            add(u,v);
            add(v,u);
        }
        if(!bfs()) printf("NO\n");
        else
        {
    
    
            solve();
            printf("YES\n");
            printf("%d\n",res);
            for(int i=1;i<=n;i++)
                if(ans[i]==1) printf("%d ",i);
            printf("\n");
        }
    }
    //system("pause");
    return 0;
}

猜你喜欢

转载自blog.csdn.net/Stevenwuxu/article/details/112795851