bzoj 1016 JSOI2008 最小生成树计数

    我都不忍心吐槽了。

    这么水的暴力我一开始竟然想写链剖!!!

    对于某个权值,相同的边不会超过10条。于是,暴力,然后乘起来。

    注意特判!特判!图不连通的时候输出0。

    我的程序在不联通的时候会输出奇怪的数字……要崩溃了……

    上代码:

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <cstdlib>
#include <cmath>
#define N 111
#define M 1011
#define yu 31011
#define inf 0x7f7f7f7f
using namespace std;

struct sss
{
    int x, y;
    int val;
}bian[M];
int n, m;
int fa[N];
int use[M] = {0}, same[15], samenum = 0;
long long ans = 1, minval;

bool cmp(sss x, sss y) { return x.val < y.val; }

int find(int x)
{
    if (fa[x] == x) return x;
    fa[x] = find(fa[x]);
    return fa[x];
}

long long kru()
{
    long long nowval = 0; int nowc = n;
    for (int i = 1; i <= n; ++i) fa[i] = i;
    for (int i = 1; i <= m; ++i)
    {
        int x = find(bian[i].x);
        int y = find(bian[i].y);
        if (use[i] == 1 && x == y) return 0; // use[i] == 1 用 2 不用 
        if (use[i] == 2) continue;
        if (x != y)
        {
            fa[x] = y;
            nowval += bian[i].val;
            nowc --;
        }
    }
    if (nowc != 1) return 0;
    else return nowval;
}

int main()
{
    scanf("%d%d", &n, &m);
    for (int i = 1; i <= m; ++i)
        scanf("%d%d%d", &bian[i].x, &bian[i].y, &bian[i].val);
    sort(bian+1, bian+1+m, cmp);
    bian[0].val = -inf; bian[m+1].val = -inf;
    minval = kru();
    if (minval == 0)
    {
        printf("0\n");
        return 0;
    }
    for (int w = 1; w <= m; ++w)
    {
        samenum = 0;
        if (bian[w].val != bian[w+1].val) continue;
        same[++samenum] = w++;
        while (bian[w].val == bian[w-1].val) {same[++samenum] = w++;}
        w--;
        int zans = 0;
        int cou = (1 << samenum)-1;
        for (int i = 0; i <= cou; ++i)
        {
            int j = i, thisb = 1;
            for (int k = 1; k  <= samenum; ++k) use[same[k]] = 2;
            while (j){if (j & 1) use[same[thisb]] = 1;j >>= 1; thisb++;}
            if (kru() == minval) zans++;
        }
        for (int i = 1; i <= samenum; ++i) use[same[i]] = 0;
        ans *= (zans%yu);
        ans %= yu;
    }
    printf("%lld\n", ans%yu);
    return 0;
}

 

posted @ 2014-10-19 10:44  handsomeJian  阅读(...)  评论(... 编辑 收藏