zoukankan      html  css  js  c++  java
  • [洛谷P4208][JSOI2008]最小生成树计数

    题目大意:$n$个点和$m$条边(最多有$10$条边边权相同),求最小生成树个数

    题解:对于所有最小生成树,每种边权的边数是一样的。于是就可以求出每种边权在最小生成树中的个数,枚举这种边的边集,求出对于这个边集可以的解(即没有一条边在同一联通块中),再把每种边的方案数乘起来即可。

    卡点:

    C++ Code:

    #include <cstdio>
    #include <algorithm>
    using namespace std;
    const long long mod = 31011;
    struct Edge {
    	int from, to, w;
    	bool operator < (const Edge &a) const {return w < a.w;}
    } e[1010];
    int n, m;
    struct Set {
    	int f[111];
    	int find(int x) {return ((x == f[x]) ? x : (f[x] = find(f[x])));}
    	bool operator = (const Set &a) {
    		for (int i = 1; i <= n; i++) f[i] = a.f[i];
    	}
    } s1, s2;
    long long ans = 1;
    int main() {
    	scanf("%d%d", &n, &m);
    	for (int i = 1; i <= m; i++) scanf("%d%d%d", &e[i].from, &e[i].to, &e[i].w);
    	sort(e + 1, e + m + 1);
    	for (int i = 1; i <= n; i++) s1.f[i] = s2.f[i] = i;
    	for (int i = 1; i <= m; i++) {
    		int same = i, cnt = 0, res = 0;
    		while (same < m && e[same].w == e[same + 1].w) same++;
    		s1 = s2;
    		for (int j = i; j <= same; j++) {
    			int u = s1.find(e[j].from), v = s1.find(e[j].to);
    			if (u != v) {
    				s1.f[u] = v;
    				cnt++;
    			}
    		}
    		for (int j = 0; j < 1 << same - i + 1; j++) {
    			bool flag = false;
    			if (__builtin_popcount(j) == cnt) {
    				flag = true;
    				s1 = s2;
    				for (int k = i; k <= same; k++) {
    					if (j & 1 << k - i) {
    						int u = s1.find(e[k].from), v = s1.find(e[k].to);
    						if (u == v) {
    							flag = false;
    							break;
    						} else s1.f[u] = v;
    					}
    				}
    			}
    			res += flag;
    		}
    		for (int j = i; j <= same; j++) {
    			int u = s2.find(e[j].from), v = s2.find(e[j].to);
    			if (u != v) s2.f[u] = v;
    		}
    		ans = (ans * res) % mod;
    	}
    	int tmp = s2.find(1);
    	for (int i = 2; i <= n; i++) if (s2.find(i) != tmp) {
    		puts("0");
    		return 0;
    	}
    	printf("%d
    ", ans);
    	return 0;
    }
    

      

  • 相关阅读:
    CentOS7.0安装Nginx 1.7.4
    Java If ... Else
    Java 布尔运算
    Java Math
    Java 运算符
    Java 数据类型
    Java 变量
    Java 注释
    Java 基本语法
    Java 简介
  • 原文地址:https://www.cnblogs.com/Memory-of-winter/p/9460584.html
Copyright © 2011-2022 走看看