欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

leetcode 1042. 不邻接植花 图的着色问题(假) 暴力dfs

程序员文章站 2022-06-09 18:03:59
...
  1. 不邻接植花

有 n 个花园,按从 1 到 n 标记。另有数组 paths ,其中 paths[i] = [xi, yi] 描述了花园 xi 到花园 yi 的双向路径。在每个花园中,你打算种下四种花之一。

另外,所有花园 最多 有 3 条路径可以进入或离开.

你需要为每个花园选择一种花,使得通过路径相连的任何两个花园中的花的种类互不相同。

以数组形式返回 任一 可行的方案作为答案 answer,其中 answer[i] 为在第 (i+1) 个花园中种植的花的种类。花的种类用 1、2、3、4 表示。保证存在答案。

示例 1:

输入:n = 3, paths = [[1,2],[2,3],[3,1]]
输出:[1,2,3]
解释:
花园 1 和 2 花的种类不同。
花园 2 和 3 花的种类不同。
花园 3 和 1 花的种类不同。
因此,[1,2,3] 是一个满足题意的答案。其他满足题意的答案有 [1,2,4]、[1,4,2] 和 [3,2,1]

示例 2:

输入:n = 4, paths = [[1,2],[3,4]]
输出:[1,2,1,2]

示例 3:

输入:n = 4, paths = [[1,2],[2,3],[3,4],[4,1],[1,3],[2,4]]
输出:[1,2,3,4]

提示:

1 <= n <= 104
0 <= paths.length <= 2 * 104
paths[i].length == 2
1 <= xi, yi <= n
xi != yi
每个花园 最多 有 3 条路径可以进入或离开

题意:给定一张无向图,给定4种颜色,要求对顶点染色,且不能出现相邻点同色

  1. 暴力dfs
  2. 对于任意一个点u,暴力找和他相邻的点的未出现过的颜色,选最小颜色的染色
  3. 图可能不连通,要对每个点dfs

typedef vector<vector<int>> VVI;
// #define MAXN (10005)
vector<int> G[MAXN];

class Solution {
public:
	int cnt;
    void dfs(int u, vector<int>& ans) {
		int vis[5] = { 0 }; vis[0] = 1;
		for(auto v : G[u]) 
			vis[ans[v]] = true;
		for(int i=1; i<=4; i++) {
			if(!vis[i]) { //选最小未出现的颜色染
				ans[u] = i;
				cnt --;
				break;
			}
		}
		for(auto v : G[u]) { //接着染未被染色的子节点
			if(ans[v]) continue ;
			dfs(v, ans);
		}
    }
    vector<int> gardenNoAdj(int n, vector<vector<int>>& g) {
        vector<int> ans(n+1, 0);
		for(int i=1; i<=n; i++) G[i].clear();
		if(n == 1 || g.empty()) goto flag;
		cnt = n;
        for(auto& ed : g) {
            int u = ed[0], v = ed[1];
            G[u].push_back(v); G[v].push_back(u);
        }
		flag : 
		for(int i=1; i<=n; i++) //图可能不连通,对每个点dfs
			if(!ans[i]) dfs(i, ans);
		reverse(ans.begin(), ans.end());
		ans.pop_back();
		reverse(ans.begin(), ans.end());

        return ans;
    }
};