题解

题目难度:中等难度
知识点:图、邻接矩阵、DFS

DFS方法思路:

步骤一:构造邻接邻接矩阵G[N]

示例一点连接情况的输入:
1 2
2 3
3 4
4 1
4 5
5 2
其G[N]为:
图片说明

步骤二:用color[N]表示点的着色情况,例如点2,color[2]=0表示点2未着色,color[2]=1表示点2上黑色,color[2]=-1表示点2上白色。

步骤三:采用DFS方法给点进行上色并判断是否发生冲突。

DFS方法:bool DFS(int u, int c),u表示着色点,c为该点的颜色,color[u] = c其含义是点u为c色。

A.通过G[u].size(),找到有几个点与U点相连接,通过G[u][i]取出连接点v。

B.依次判断其连接点v的着色情况:

aa..如果color[v]=c,表示u和其连接点着色冲突,因此直接返回false。

bb.如果连接点未着色即color[v]=0,那么我们将其颜色设置未-color,并且通过DFS(v, -c)判断v点与其邻接点是否冲突。如果DFS(v, -c)的返回值为false,那么存在冲突,因此DFS(u, c)直接返回false;如果不冲突,接着判断u的下一个邻接点。

cc.如果color[v]=-c,表示其邻接点已经着色,并且没有发生冲突,直接判断下一个邻接点。

C.当判断完所有邻接点(在循环过程中没有return),那么表示u与所有的邻接点未发生冲突,即return true。

步骤四:如果该图为连通图,那么我们只需要一次DFS即可判断是否可以着色。但是该题目中说明了此图可能不连通,所以在主函数中需要添加一层循环,遍历所有点。首先判断该点是否已经着色,若未着色从该点进行新一轮的DFS。

#include <iostream>
#include<vector>
#define N 100007
using namespace std;
int n,m;
vector<int> G[N];
int color[N];

bool DFS(int u, int c){
    color[u] = c;
    for(int i=0;i<G[u].size();i++){
        int v = G[u][i];
        if(color[v]==c)
            return false;
        if(color[v]==0 && !DFS(v, -c))
            return false;
    }
    return true;
}

int main(){
    cin>>n>>m;
    for(int i=0;i<m;i++){
        int u,v;
        cin>>u>>v;
        G[u].push_back(v);
        G[v].push_back(u);
    }
    bool flag = true;
    for(int i=1;i<=n;i++){
        if(color[i]==0 && !DFS(i,1)){
            flag = false;
            break;
        }
    }
    cout<<(flag?"Yes":"No")<<endl;
    return 0;
}