分享web开发知识

注册/登录|最近发布|今日推荐

主页 IT知识网页技术软件开发前端开发代码编程运营维护技术分享教程案例
当前位置:首页 > 运营维护

BZOJ 1016[JSOI2008]最小生成树计数

发布时间:2023-09-06 01:13责任编辑:彭小芳关键词:暂无标签

问一个图最小生成树的个数,n<100,m<1000,规定相同权值的边不超过10条。

每天午觉起来很长一段时间都仿佛活在梦中。上午看的下午来打,狂RE不止,发现一种边只有一条的情况没有r会GG。。

//Twenty#include<cstdio>#include<cstdlib>#include<iostream>#include<algorithm>#include<cmath>#include<cstring>#include<queue>#include<vector>typedef long long LL;const int maxn=100+5;const int maxm=1000+5;const int mod=31011;using namespace std;int ans=1,sum,n,m,fa[maxn],ecnt,tot;struct edge{ ???int u,v,l,r,w,o; ???friend bool operator <(const edge &A,const edge &B) { ????????return A.w<B.w; ???}}e[maxm],ee[maxm];void init() { ???scanf("%d%d",&n,&m); ???for(int i=1;i<=m;i++) ????????scanf("%d%d%d",&e[i].u,&e[i].v,&e[i].w); }int find(int x) {return x==fa[x]?x:find(fa[x]);}void kruskal() { ???sort(e+1,e+m+1); ???for(int i=1;i<=n;i++) fa[i]=i; ???for(int i=1;i<=m;i++) { ???????int u=e[i].u,v=e[i].v; ???????if(tot==n-1&&e[i].w!=ee[ecnt].w) break; ???????u=find(u),v=find(v); ???????if(!ecnt||e[i].w!=ee[ecnt].w) { ???????????????ee[++ecnt].l=i; ???????????????ee[ecnt].w=e[i].w; ???????} ???????ee[ecnt].r=i; ???????if(u!=v) { ??????????fa[u]=v; ??????????tot++; ??????????ee[ecnt].o++; ???????} ???}}void dfs(int id,int now,int k) { ???if(now==ee[id].r+1&&k==ee[id].o) sum++; ???if(now==ee[id].r+1) return ; ???int res=0; ???int u=find(e[now].u),v=find(e[now].v); ???if(u!=v) { ???????fa[u]=v; ???????dfs(id,now+1,k+1); ???????fa[u]=u; fa[v]=v; ???} ???dfs(id,now+1,k);}void work() { ???kruskal(); ???if(tot!=n-1) {printf("0"); return ;} ???for(int i=1;i<=n;i++) fa[i]=i; ???for(int i=1;i<=ecnt;i++) { ???????sum=0; ???????dfs(i,ee[i].l,0); ???????ans=(ans*sum)%mod; ???????for(int j=ee[i].l;j<=ee[i].r;j++) { ???????????int u=find(e[j].u),v=find(e[j].v); ???????????if(u!=v) fa[u]=v; ???????} ???} ???printf("%d\n",ans);}int main(){ ???init(); ???work(); ???return 0;}
View Code

最小生成树的两个性质: 
(1)不同的最小生成树中,每种权值的边出现的个数是确定的 
(2)不同的生成树中,某一种权值的边连接完成后,形成的联通块状态是一样的 

有了这两个性质,先跑一遍Kruskal求出最小生成树和每种权值的边分别出现的次数,因为相同权值的边很少,对于每种权值的边直接爆搜,乘法原理。

若是没有这个次数限制,就要用矩阵树定理解决。

BZOJ 1016[JSOI2008]最小生成树计数

原文地址:http://www.cnblogs.com/Achenchen/p/7581361.html

知识推荐

我的编程学习网——分享web前端后端开发技术知识。 垃圾信息处理邮箱 tousu563@163.com 网站地图
icp备案号 闽ICP备2023006418号-8 不良信息举报平台 互联网安全管理备案 Copyright 2023 www.wodecom.cn All Rights Reserved