zoukankan      html  css  js  c++  java
  • cf804C(dfs染色)

    题目链接: http://codeforces.com/problemset/problem/804/C

    题意: 有一颗含有 n 个顶点的树, 第 i 个顶点上有 k 个冰激凌, 每个冰激凌的种类为 si . 现在要给所有定点上的冰激凌染色 , 要求相同种类的冰激凌染相同的颜色, 并且同一个顶点上的冰激凌要求染不同颜色.

    注意: 同一个顶点中不会出现相同的冰激凌

    思路: dfs染色

    首先因该考虑最多需要多少中颜色, 然后再考虑怎么染色. 对于一种冰激凌, 如果确定了其染什么颜色, 那么在后面其他顶点中遇到这中冰激凌也直接染成这种颜色即可.

    对于一种在其它顶点中用过的颜色, 若在当前顶点中没有用过, 那么可以将当前顶点中某个冰激凌染成这种颜色. 显然, 限制所需颜色种数的条件为 max(ki), 并且最少需要的颜色种数即为: max(ki). 至于具体染色方案只需 dfs 一遍即可. dfs 过程为: 在当前顶点中, 对于之前染过色的冰激凌, 先给它染上同种颜色, 对于剩下的冰激凌, 依次选取当前最小的且当前顶点中没用过的颜色染上即可.

    代码:

     1 #include <iostream>
     2 #include <stdio.h>
     3 #include <vector>
     4 #include <string.h>
     5 #include <map>
     6 using namespace std;
     7 
     8 const int MAXN = 3e5 + 10;
     9 vector<int> vt1[MAXN], vt2[MAXN];
    10 map<int, int> vis;
    11 int sol[MAXN];
    12 
    13 void dfs(int x, int pre){
    14     // memset(vis, 0, sizeof(vis));用数组标记会tle
    15     vis.clear();
    16     for(int i = 0; i < vt1[x].size(); i++){
    17         if(sol[vt1[x][i]]) vis[sol[vt1[x][i]]] = 1;//记录前面用过的颜色
    18     }
    19     int cnt = 0;
    20     for(int i = 0; i < vt1[x].size(); i++){
    21         if(sol[vt1[x][i]]) continue;
    22         while(vis[++cnt]){};
    23         sol[vt1[x][i]] = cnt;//将没有标记的冰激凌染上新颜色
    24     }
    25     for(int i = 0; i < vt2[x].size(); i++){
    26         if(vt2[x][i] != pre) dfs(vt2[x][i], x);
    27     }
    28 }
    29 
    30 int main(void){
    31     int n, m, k, x, y, ans = 1;
    32     scanf("%d%d", &n, &m);
    33     for(int i = 1; i <= n; i++){
    34         scanf("%d", &k);
    35         if(ans < k) ans = k;
    36         while(k--){
    37             scanf("%d", &x);
    38             vt1[i].push_back(x);
    39         }
    40     }
    41     for(int i = 1; i < n; i++){
    42         scanf("%d%d", &x, &y);
    43         vt2[x].push_back(y);
    44         vt2[y].push_back(x);
    45     }
    46     dfs(1, -1);
    47     printf("%d
    ", ans);
    48     for(int i  = 1; i <= m; i++){
    49         if(sol[i]) printf("%d ", sol[i]);
    50         else printf("1 ");
    51     }
    52     puts("");
    53     return 0;
    54 }
    View Code
  • 相关阅读:
    用例图解析
    A B C D类网络地址
    B-树特征
    常用的中间代码
    UML图
    关于文件索引的一道习题
    数据流图的一些原则
    系统总线
    各种排序方法的时间复杂度、空间复杂度和稳定性统计表
    模拟银行自助终端系统
  • 原文地址:https://www.cnblogs.com/geloutingyu/p/7127360.html
Copyright © 2011-2022 走看看