zoukankan      html  css  js  c++  java
  • BZOJ 1016: [JSOI2008]最小生成树计数

    二次联通门 : BZOJ 1016: [JSOI2008]最小生成树计数

    /*
        BZOJ 1016: [JSOI2008]最小生成树计数
    
        对原图做一遍Kruskal最小生成树,统计不同边使用的次数
        每次暴力统计一下
        答案乘一乘就好了
    */
    #include <cstdio>
    #include <iostream>
    #include <algorithm>
    #define rg register
    #define Mod 31011
    #define Max 1009
    inline void read (int &n)
    {
        rg char c = getchar ();
        for (n = 0; !isdigit (c); c = getchar ());
        for (; isdigit (c); n = n * 10 + c - '0', c = getchar ());
    }
    struct E 
    { 
        int u, v, d;
        bool operator < (const E &rhs) const { return d < rhs.d; }
    } e[Max]; int f[Max / 10 + 3], C, T, p;
    struct D { int v, s, l, r; } g[Max];
    int Find (int x) { return f[x] == x ? x : Find (f[x]); }
    void Dfs (int n, int t, int i)
    {
        if (n == g[i].r + 1) { if (t == g[i].s) ++ p; return ; }
        Dfs (n + 1, t, i); int x = Find (e[n].u), y = Find (e[n].v);
        if (x != y) f[x] = y, Dfs (n + 1, t + 1, i), f[x] = x;
    }
    int main (int argc, char *argv[])
    {
        int N, M, x, y, r, s = 1; read (N), read (M); rg int i, j;
        for (i = 1; i <= M; ++ i) read (e[i].u), read (e[i].v), read (e[i].d);
        std :: sort (e + 1, e + 1 + M); for (i = 1; i <= N; f[i] = i, ++ i);
        for (i = 1; i <= M; ++ i)
        {
            if (e[i].d != g[C].v) g[C].r = i - 1, g[++ C].l = i, g[C].v = e[i].d;
            x = Find (e[i].u), y = Find (e[i].v);
            if (x != y) f[x] = f[y], ++ T, ++ g[C].s;
            if (T == N - 1) { r = i; break; }
        }
        if (T != N - 1) return printf ("0"), 0;
        for (i = r + 1; i <= M; ++ i) if (e[i].d == g[C].v) r = i;
        for (g[C].r = r, i = 1; i <= N; f[i] = i, ++ i);
        for (i = 1; i <= C; ++ i)
        {
            if (g[i].s == 0) continue;
            p = 0, Dfs (g[i].l, 0, i), s = s * p % Mod;
            for (j = g[i].l; j <= g[i].r; ++ j)
            {
                x = Find (e[j].u), y = Find (e[j].v);
                if (x != y) f[x] = y;
            }
        }
        printf ("%d", s); return 0;
    }
  • 相关阅读:
    关于一个单机游戏发行的一些见解
    怎么租借电话号码
    NUMA架构的优缺点
    Windows 安装PostgreSQL
    Oracle查询当前用户下的所有表及sqlplus 设置 列宽
    Xshell调整终端显示的最大行数(缓冲区)
    PostgreSQL 索引膨胀
    Linux 清空缓存
    load多个数据文件的yaml
    Linux LVM逻辑卷配置过程详解(创建,增加,减少,删除,卸载)
  • 原文地址:https://www.cnblogs.com/ZlycerQan/p/7576848.html
Copyright © 2011-2022 走看看