• 【dfs+理解题意+构造】【待重做】codeforces E. Ice cream coloring


    http://codeforces.com/contest/805/problem/E

    【题意】

    染色数是很好确定,最少染色数是max(si)(最小为1,即使所有的si都为0,这样是单节点树形成的森林需要1种颜色),关键是确定染色方案。

    一开始没看出来树有什么用,但其实一句话很关键:Vertices which have the i-th (1 ≤ i ≤ m) type of ice cream form a connected subgraph.

    也就是说在原来的图中,含有相同的冰淇淋的点是一个 联通子图。那么比如1,2在一个点,1,3在一个点,那么2,3便不可能在另一个点了,因为那样将会形成一个环,也就是说这个图不再是树了。

    因为每种冰淇淋所在的所有点在这颗树上是一个连通块,也就是说,沿着树搜索下去,不可能出现已经染过色且父亲中没有的冰淇淋重新出现的问题。于是就可以直接贪心构造一波就行了。” 然而这里还是每太明白,为什么这样构造......

    【Accepted】

      1 #include <iostream>
      2 #include <stdio.h>
      3 #include <cmath>
      4 #include <vector>
      5 #include <algorithm>
      6 #include <set>
      7 #include <map>
      8 #include <queue>
      9 #include <deque>
     10 #include <stack>
     11 #include <string>
     12 #include <bitset>
     13 #include <ctime>
     14 #include<algorithm>
     15 #include<cstring>
     16 using namespace std;
     17 typedef long long ll;
     18 int n,m;
     19 const int maxn=3e5+5;
     20 vector<int> s[maxn];
     21 int num[maxn];
     22 int c[maxn];
     23 struct node
     24 {
     25     int to;
     26     int nxt;
     27 }edge[maxn<<1];
     28 int head[maxn];
     29 int tot;
     30 int res;
     31 void add(int u,int v)
     32 {
     33     edge[tot].nxt=head[u];
     34     edge[tot].to=v;
     35     head[u]=tot++;
     36 }
     37 
     38 void Init()
     39 {
     40     res=1;
     41     tot=0;
     42     memset(c,0,sizeof(c));
     43     memset(head,-1,sizeof(head));
     44 }
     45 void dfs(int u,int pre)
     46 {
     47     res=max(res,num[u]);
     48     set<int> t;
     49     t.clear();
     50     for(int i=0;i<num[u];i++)
     51     {
     52         int v=s[u][i];
     53         if(c[v])
     54         {
     55             t.insert(c[v]);
     56         }
     57     }
     58     int temp=0;
     59     for(int i=0;i<num[u];i++)
     60     {
     61         int v=s[u][i];
     62         if(!c[v])
     63         {
     64             temp++;
     65             while(t.count(temp))
     66             {
     67                 temp++;
     68             }
     69             c[v]=temp;
     70         }
     71     }
     72     for(int i=head[u];i!=-1;i=edge[i].nxt)
     73     {
     74         int to=edge[i].to;
     75         if(to!=pre)
     76         {
     77             dfs(to,u);
     78         }
     79     }
     80 }
     81 int main()
     82 {
     83     while(~scanf("%d%d",&n,&m))
     84     {
     85         Init();
     86         for(int i=1;i<=n;i++)
     87         {
     88             scanf("%d",&num[i]);
     89             s[i].clear();
     90             for(int k=0;k<num[i];k++)
     91             {
     92                 int x;
     93                 scanf("%d",&x);
     94                 s[i].push_back(x);
     95             }
     96         }
     97         int u,v;
     98         for(int i=0;i<n-1;i++)
     99         {
    100             scanf("%d%d",&u,&v);
    101             add(u,v);
    102             add(v,u);
    103         }
    104         dfs(1,0);
    105         for(int i=1;i<=m;i++)
    106         {
    107             if(!c[i])
    108             {
    109                 c[i]=1;
    110             }
    111         }
    112         cout<<res<<endl;
    113         cout<<c[1];
    114         for(int i=2;i<=m;i++)
    115         {
    116             cout<<" "<<c[i];
    117         }
    118         cout<<endl;    
    119     }
    120     return 0;
    121  } 
    View Code
  • 相关阅读:
    Android 剪贴板操作方法在不同版本API下的使用
    Android android:persistentDrawingCache的几个默认属性值介绍
    android 4.0 external下功能库说明
    Android gc overhead limit exceeded
    android onTerminate()方法调用需要注意的点
    android onTrimMemory()和onLowMemory()
    思维游戏(3)之时间问题
    思维游戏(2)之几根蜡烛
    思维游戏之分辨姐妹(1)
    如何根据用例图写出用例描述
  • 原文地址:https://www.cnblogs.com/itcsl/p/6947173.html
Copyright © 2020-2023  润新知