(LeetCode 886)可能的二分法 [01着色问题,dfs模拟]

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/STILLxjy/article/details/85541457

886. 可能的二分法
给定一组 N 人(编号为 1, 2, …, N), 我们想把每个人分进任意大小的两组。

每个人都可能不喜欢其他人,那么他们不应该属于同一组。

形式上,如果 dislikes[i] = [a, b],表示不允许将编号为 a 和 b 的人归入同一组。

当可以用这种方法将每个人分进两组时,返回 true;否则返回 false。

示例 1:

输入:N = 4, dislikes = [[1,2],[1,3],[2,4]]
输出:true
解释:group1 [1,4], group2 [2,3]
示例 2:

输入:N = 3, dislikes = [[1,2],[1,3],[2,3]]
输出:false
示例 3:

输入:N = 5, dislikes = [[1,2],[2,3],[3,4],[4,5],[1,5]]
输出:false

提示:

1 <= N <= 2000
0 <= dislikes.length <= 10000
1 <= dislikes[i][j] <= N
dislikes[i][0] < dislikes[i][1]
对于 dislikes[i] == dislikes[j] 不存在 i != j

分析:
本题就是直接使用DFS(或BFS)进行模拟。将所有人分为两组,就是给所有人在0,1两种颜色上着色,使其不冲突。

首先所有的节点都没有着色,标记为-1。
对任意的联通分量,第一个节点我们可以随意着色,(着色为1),然后进行DFS对其他相邻的节点进行着色。
若该节点没有被着色,则将其着色为另外一种颜色,并递归对其相邻节点进行着色。
若该节点已经着色,则只需判断这两个相邻的节点的颜色是否相同,相同则存在冲突。

AC代码:

class Solution {
public:
    int c[2019];
    vector<int> e[2019];
    
    int dfs(int id,int color)
    {
        c[id] = color;
        int ans = 1;
        for(int i=0;i<e[id].size();i++)
        {
            if(c[e[id][i]] == -1) ans &= dfs(e[id][i],color^1);
            else if(c[e[id][i]] == color)
            {
                ans = 0;
                break;
            }
        }
        return ans;
    }
    
    bool possibleBipartition(int N, vector<vector<int>>& dislikes) {
        if(N<=2) return true;
        memset(c,-1,sizeof(c));
        int m = dislikes.size();
        for(int i=0;i<m;i++)
        {
            e[dislikes[i][0]].push_back(dislikes[i][1]);
            e[dislikes[i][1]].push_back(dislikes[i][0]);
        }
        int ans = 1;
        for(int i=1;i<=N;i++)
        {
            if(c[i] == -1)
                ans &= dfs(i,1);
        }
        return ans;
    }
};

猜你喜欢

转载自blog.csdn.net/STILLxjy/article/details/85541457