1016: [JSOI2008]最小生成树计数
来源:互联网 发布:base64 js 源码 编辑:程序博客网 时间:2024/05/19 15:41
1016: [JSOI2008]最小生成树计数
Time Limit: 1 Sec Memory Limit: 162 MBSubmit: 4162 Solved: 1673
[Submit][Status][Discuss]
Description
现在给出了一个简单无向加权图。你不满足于求出这个图的最小生成树,而希望知道这个图中有多少个不同的最小生成树。(如果两颗最小生成树中至少有一条边不同,则这两个最小生成树就是不同的)。由于不同的最小生成树可能很多,所以你只需要输出方案数对31011的模就可以了。
Input
第一行包含两个数,n和m,其中1<=n<=100; 1<=m<=1000; 表示该无向图的节点数和边数。每个节点用1~n的整数编号。接下来的m行,每行包含两个整数:a, b, c,表示节点a, b之间的边的权值为c,其中1<=c<=1,000,000,000。数据保证不会出现自回边和重边。注意:具有相同权值的边不会超过10条。
Output
输出不同的最小生成树有多少个。你只需要输出数量对31011的模就可以了。
Sample Input
4 6
1 2 1
1 3 1
1 4 1
2 3 2
2 4 1
3 4 1
1 2 1
1 3 1
1 4 1
2 3 2
2 4 1
3 4 1
Sample Output
8
HINT
Source
暴力大法好。。。
对于最小生成树,同一种权值边使用次数一样
因为在两种方案里若同种权值边使用次数不同,必有一种更优
然后每种边不超过10条
每种爆搜即可
#include<iostream>#include<cstdio>#include<cstdlib>#include<algorithm>#include<cstring>#include<cmath>#include<vector>#include<queue>using namespace std;typedef long long LL;const LL mo = 31011;const int maxn = 1E2 + 10;const int maxm = maxn*10;struct E{int u,v,w;bool operator < (const E&b) const {return w < b.w;}}e[maxn*10];int n,m,cur = 1,fa[maxn],use[maxm],num[maxm];int a[maxm],po;LL ans = 1,sum;int father(int k){return k == fa[k]?k:father(fa[k]);}void dfs(int x,int tot){if (x == a[po]+1) {if (tot == use[po]) ++sum; return;}if (a[po] - x + 1 + tot < use[po]) return;int fu = father(e[x].u);int fv = father(e[x].v);if (fu != fv) {fa[fu] = fv;dfs(x+1,tot+1);fa[fu] = fu;}dfs(x+1,tot);}int main(){#ifdef YZY freopen("yzy.txt","r",stdin);#endifcin >> n >> m;for (int i = 1; i <= m; i++) {int u,v,w;scanf("%d%d%d",&u,&v,&w);e[i] = (E){u,v,w};num[i] = w;}for (int i = 1; i <= n; i++) fa[i] = i;sort(e+1,e+m+1);sort(num+1,num+m+1);for (int i = 2; i <= m; i++)if (num[i] != num[i-1])num[++cur] = num[i]; int tot = 0;for (int i = 1; i <= m; i++) {int fu = father(e[i].u);int fv = father(e[i].v);int pos = lower_bound(num+1,num+cur+1,e[i].w) - num;if (fu != fv) {fa[fu] = fv;++tot;++use[pos];}if (e[i].w != e[i-1].w) a[pos-1] = i-1;}a[cur] = m;if (tot != n-1) {cout << 0;return 0;}for (int i = 1; i <= n; i++) fa[i] = i;for (int i = 1; i <= m; i++)if (e[i].w != e[i-1].w) {sum = 0;po = lower_bound(num+1,num+cur+1,e[i].w) - num;dfs(i,0);ans = ans*sum%mo;for (int j = i; j <= a[po]; j++) {int fu = father(e[j].u);int fv = father(e[j].v);if (fu != fv) fa[fu] = fv;}}cout << ans;return 0;}
1 0
- 1016: [JSOI2008]最小生成树计数
- 【BZOJ 1016】 [JSOI2008]最小生成树计数
- BZOJ 1016: [JSOI2008]最小生成树计数
- 1016: [JSOI2008]最小生成树计数
- BZOJ 1016 [JSOI2008]最小生成树计数
- BZOJ 1016 [JSOI2008] 最小生成树计数
- 1016: [JSOI2008]最小生成树计数
- [BZOJ]1016: [JSOI2008]最小生成树计数
- bzoj 1016: [JSOI2008]最小生成树计数
- 1016: [JSOI2008]最小生成树计数
- bzoj 1016: [JSOI2008]最小生成树计数
- bzoj 1016: [JSOI2008]最小生成树计数
- [JSOI2008]最小生成树计数
- BZoj 1016: [JSOI2008]最小生成树计数【最小生成树】
- BZOJ 1016 JSOI2008 最小生成树计数 Kruskal
- 【bzoj 1016】[JSOI2008]最小生成树计数 脑残是病
- [bzoj 1016] [JSOI2008]最小生成树计数:Kruskal,枚举
- 【BZOJ 1016】[JSOI2008]最小生成树计数 基尔霍夫矩阵||暴力
- 智能的最小单元
- zstu 1024 Wooden Sticks
- Mac下利用shadowsocks配置Dropbox代理服务器
- 关于用struts2框架中iframe对应的jsp页面的不到action的值的问题
- Leetcode ☞ 319. Bulb Switcher ☆ brain teaser
- 1016: [JSOI2008]最小生成树计数
- MySQL知识(二十一)——用户管理之权限管理、访问控制
- 从Eclipse迁移到Android Studio
- 认识数据仓库建设意义
- c语言:求三个数中的最大值(双分支结构)
- JavaScript 垃圾回收
- 【Manthan, Codefest 16B】【二分 or 递推暴力】A Trivial Problem 输出阶乘为m的所有数
- 微信-弹幕是怎么搞出来的,看svg!
- [LeetCode]62 不同的路径总数