zoukankan      html  css  js  c++  java
  • 两个给点染色的问题-树上染色与图上染色

    两个给点染色的问题

    写在前面:最近做了两个染色问题,都是问染色方案数,但是解题方法完全不同。

    Coloring Tree @牛客网暑期ACM多校训练营(第三场)G

    PROBLEM1 【bfs】【树上染色问题】

    题目描述

    Christmas is coming! Eddy has received a Christmas tree as gift. Not surprisingly, the tree consists of N vertices and N-1 edges and magically remains connected. Currently, all the vertex of the tree is uncolored. Eddy wants to color each vertex into one of K colors. However, there are too many way to color the tree(i.e. KN ways). Eddy doesn't want the result of coloring being too boring. Thus, he defines the colorness of a tree as follow:
    The colorness of a tree is the minimum distance between two vertex colored in the same color.
    Now, Eddy is wondering how many way to color the tree such that the colorness of the tree will be D.

    输入描述:

    The first line of input contains three space-separated integer N, K, D indicating the number of vertices, number of colors, and the required colorness.
    For each following N-1 lines, each contains two space-separated positive integer ui, vi indicating that there's an edge between ui and vi.
    1 ≤ K < N ≤ 5000
    1 ≤ D ≤ N
    1 ≤ ui < vi ≤ N
    It's guaranteed that the given input is a tree.

    输出描述:

    Output one line contains an integer indicating the number of way module 1000000007(109+7) to color the tree resulting in colorness being D.

    示例1

    输入
    2 1 1
    1 2
    输出
    1

    示例2

    输入
    4 3 2
    1 2
    2 3
    3 4
    输出
    18

    示例3

    输入
    4 3 2
    1 2
    1 3
    1 4
    输出
    24

    MEANING1

    一个n个结点的树,用k种颜色给树上的结点染色,要求相同染色结点距离恰好为d。问染色方案数。

    SOLUTION1

    构建一个函数f(d),表示相同颜色的点的距离至少为d时,染色的方案数。
    那么答案就等于f(d)-f(d+1)。
    至于求解f(d),可以用bfs的方法,确定染色顺序。对于当前点再做一次bfs,统计与他距离不超过d的已经染色的点的数量m,这些点一定是不同色的,所以当前点可选颜色数为max(k-m,0)。
    将每个点的方案数相乘就是总方案数。
    时间复杂度o((N^2))。

    CODE1

    #define IN_PC() freopen("C:\Users\hz\Desktop\in.txt","r",stdin)
    #define IN_LB() freopen("C:\Users\acm2018\Desktop\in.txt","r",stdin)
    #define OUT_PC() freopen("C:\Users\hz\Desktop\out.txt","w",stdout)
    #define OUT_LB() freopen("C:\Users\acm2018\Desktop\out.txt","w",stdout)
    #include <bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    const int MAXN = 5005;
    //const int INF = 0x3f3f3f3f;
    const ll MOD = 1e9 + 7;
    
    int numV, numC, rd;
    
    struct edge {
        int v, nex;
    } ed[MAXN * 2];
    
    int cnt, head[MAXN];
    
    void addedge(int u, int v) {
        cnt++;
        ed[cnt].v = v;
        ed[cnt].nex = head[u];
        head[u] = cnt;
    }
    
    int vis[MAXN],vis2[MAXN];
    
    struct node {
        int name, step;
    };
    
    int bfs(int cur, int d) {
        memset(vis2, 0, sizeof vis2);
        int cnt = 0;
        queue<node> q2;
        q2.push({cur, 0});
        vis2[cur] = 1;
        while(!q2.empty()) {
            int u = q2.front().name, step = q2.front().step;
            q2.pop();
            for(int i = head[u]; i; i = ed[i].nex) {
                int v = ed[i].v;
                if(vis[v] && step + 1 < d && !vis2[v]) {
                    q2.push({v, step + 1});
                    vis2[v] = 1;
                    cnt++;
                }
            }
        }
        return cnt;
    }
    
    ll fun(int d) {
        memset(vis,0,sizeof vis);
        ll res = 1;
        queue<int> q1;
        q1.push(1);
        while(!q1.empty()) {
            int cur = q1.front();
            vis[cur] = 1;
            q1.pop();
            res = res * (numC - bfs(cur, d)) % MOD;
            for(int i = head[cur]; i; i = ed[i].nex) {
                int v = ed[i].v;
                if(!vis[v])
                    q1.push(v);
            }
        }
        return res;
    }
    
    int main() {
    //    IN_PC();
        scanf("%d%d%d", &numV, &numC, &rd);
        for(int i = 0; i < numV - 1; i++) {
            int u, v;
            scanf("%d%d", &u, &v);
            addedge(u, v);
            addedge(v, u);
        }
        printf("%lld
    ", (fun(rd) - fun(rd + 1) + MOD) % MOD);
        return 0;
    }
    
    

    Coloring Dominoes @ABC071&ARC081

    PROBLEM2 【图上染色问题】

    题目描述

    We have a board with a 2×N grid. Snuke covered the board with N dominoes without overlaps. Here, a domino can cover a 1×2 or 2×1 square.
    Then, Snuke decided to paint these dominoes using three colors: red, cyan and green. Two dominoes that are adjacent by side should be painted by different colors. Here, it is not always necessary to use all three colors.
    Find the number of such ways to paint the dominoes, modulo 1000000007.
    The arrangement of the dominoes is given to you as two strings S1 and S2 in the following manner:
    Each domino is represented by a different English letter (lowercase or uppercase).
    The j-th character in Si represents the domino that occupies the square at the i-th row from the top and j-th column from the left.
    Constraints
    1≤N≤52
    |S1|=|S2|=N
    S1 and S2 consist of lowercase and uppercase English letters.
    S1 and S2 represent a valid arrangement of dominoes.

    输入

    Input is given from Standard Input in the following format:
    N
    S1
    S2

    输出

    Print the number of such ways to paint the dominoes, modulo 1000000007.

    样例输入

    3
    aab
    ccb

    样例输出

    6

    MEANING2

    2N的棋盘用1x2和2x1的色块覆盖,相邻色块不重复 。问覆盖方法数

    SOLUTION2

    与树上染色不同,图上染色不能bfs,因为对于当前点,它相邻的已经染色的点可能不同色,也可能同色,不同情况当前点可选的颜色是不同的。

    CODE2

    #define IN_PC() freopen("C:\Users\hz\Desktop\in.txt","r",stdin)
    #define IN_LB() freopen("C:\Users\acm2018\Desktop\in.txt","r",stdin)
    #define OUT_PC() freopen("C:\Users\hz\Desktop\out.txt","w",stdout)
    #define OUT_LB() freopen("C:\Users\acm2018\Desktop\out.txt","w",stdout)
    #include <bits/stdc++.h>
     
    using namespace std;
    typedef long long ll;
    const int MAXN = 53;
    const ll MOD = 1000000007;
    char mapp[2][MAXN];
    
    int main() {
    //    IN_PC();
        int n;
        scanf("%d", &n);
        for(int i = 0; i < 2; i++)
            scanf("%s", mapp[i]);
        ll ans = 1;
        for(int i = 0; i < n; i++) {
            if(mapp[0][i] != mapp[1][i]) {
                if(i == 0)ans *= 6;
                else if(mapp[0][i-1]==mapp[1][i-1])ans = (ans * 2) % MOD;
                else ans = (ans * 3) % MOD;
                i ++;
            } else {
                if(i == 0)ans *= 3;
                else if(mapp[0][i-1]==mapp[1][i-1])ans = (ans * 2) % MOD;
                else ans = ans * 1 % MOD;
            }
        }
        printf("%lld
    ", ans);
        return 0;
    }
    
  • 相关阅读:
    CSS书写技巧(转)
    OutputCache祥解
    [推荐/译文/转]从底层角度看ASP.NETA lowlevel Look at the ASP.NET Architecture
    [转]ASP.NET页面解析
    .NET开发中你可能会用到的常用方法总结
    asp.net 页面清除缓存
    ASP.NET内部原理(HttpHandler和HttpModule)
    .NET开发中你可能会用到的常用方法总结(2)
    C#解析HTML
    如何理解IIS 7的两种应用程序池的管道模式(Managed Pipeline Mode)
  • 原文地址:https://www.cnblogs.com/NeilThang/p/9397747.html
Copyright © 2011-2022 走看看