zoukankan      html  css  js  c++  java
  • 【Codeforces Round #411 (Div. 1)】Codeforces 804C Ice cream coloring (DFS)

    传送门

    分析

    这道题做了好长时间,题意就很难理解。
    我们注意到这句话Vertices which have the i-th (1 ≤ i ≤ m) type of ice cream form a connected subgraph
    也就是说在最后的图中相同颜色的点构成一个连通图
    也就是说如果1和2、3在不同的点共同出现,那么2和3一定不会在某个点共同出现。于是我们可以直接暴力dfs,在每个点对没有颜色的冰激凌贪心染最小的颜色。
    需要注意有某种冰激凌没有出现的情况。

    trick

    代码

    #include <iostream>
    #include <cstdio>
    #include <vector>
    #include <cstring>
    #include <map>
    #include <cstdlib>
    #include <cmath>
    #include <string>
    #include <algorithm>
    #include <set>
    #include <stack>
    #include <queue>
    #include <utility>
    #include <bitset>
    #define fi first
    #define se second
    #define mkp make_pair
    #define pb push_back
    #define rep(i,a,b) for (int i=(a);i<(b);i++)
    #define per(i,b,a) for (int i=(b)-1;i>=(a);i--)
    #define REP(i,a,b) for (int i=(a);i<=(b);i++)
    #define PER(i,b,a) for (int i=(b);i>=(a);i--)
    using namespace std;
    typedef long long LL;
    
    const int INF = 0x3f3f3f3f;
    
    const int MAXN = 1000005; // 1e6;
    int n,m;
    vector<int>G[MAXN];
    set<int> S[MAXN];
    int ans;
    int c[MAXN];
    void dfs(int i, int fa)
    {
            vector<int> used;
            if (fa==-1)
            {
                    for (int x:S[i])
                    {
                            c[x] = ++ans;
                            //printf("c[%d]=%d
    ",x,c[x]);
                    }
            }
            else
            {
                    for (int x:S[i])
                    {
                            if (c[x] != 0) used.pb(c[x]);
                    }
                    sort(used.begin(), used.end());
                    int now = 1,ite = 0;
                    for (int x:S[i])
                    {
                            if (c[x] == 0)
                            {
                                    while(ite < used.size())
                                    {
                                            if (now == used[ite]) ite++, now ++;
                                            else break;
                                    }
                                    c[x]=now;
                                    //printf("c[%d]=%d
    ",x,c[x]);
                                    now++;
                            }
                    }
                    ans = max(ans,now-1);
            }
            rep(j,0,G[i].size())
            {
                    int v = G[i][j];
                    if (v==fa) continue;
                    dfs(v,i);
            }
    }
    
    int main()
    {
            scanf("%d%d",&n,&m);
            rep(i,1,n+1)
            {
                    int si;
                    scanf("%d",&si);
                    rep(j,0,si)
                    {
                            int c;
                            scanf("%d",&c); S[i].insert(c);
                    }
            }
            rep(i,1,n)
            {
                    int u,v;
                    scanf("%d%d",&u,&v);G[u].pb(v);G[v].pb(u);
            }
            dfs(1,-1);
    
            if (ans == 0) ans = 1;
            printf("%d
    ",ans);
    
            rep(i,1,m+1)
            {
                    if (c[i]==0) c[i]=1;
                    printf("%d%c",c[i]," 
    "[i==m]);
            }
    }
    
  • 相关阅读:
    【知识强化】第六章 查找 6.4 散列(Hash)表
    【知识强化】第七章 排序 7.5 归并排序和基数排序
    【知识强化】第六章 查找 6.3 B树和B+树
    【知识强化】第五章 图 5.4 图的应用
    【知识强化】第五章 图 5.3 图的遍历
    linux的自启动服务脚本的(/etc/rc.d/init.d或者其链接/etc/init.d)
    shell文件包含
    shell输入输出重定向
    shell函数参数
    shell函数
  • 原文地址:https://www.cnblogs.com/chendl111/p/6840208.html
Copyright © 2011-2022 走看看