bzoj1016: [JSOI2008]最小生成树计数 MST+DFS
来源:互联网 发布:云南网络广播电视台 编辑:程序博客网 时间:2024/05/06 04:43
经典搜索,在求MST的同时可以维护一个集合,即在相同长度的边的集合中能包含进sum个新的点,dfs中先求这条边不连,后面(r-l)-1条边更新sum个点的方案数,再加上引用这条边能增加的方案数。 由于dfs中的最小树有改变,所以getfather2应该用递归实现。
因为我们可以把不同的最小生成树理解为把边按照不同的顺序排序做kruskal。但是kruskal又要求按从小到大排所以能换顺序的只有权值相同的
然 后按权值分组,我们全部选了能够得到一个连通情况,接下来就枚举那些边选,如果这些边不构成环并且选了之后的联通情况跟全选一样,这就是对于这组边的一种 选法了吧。而判断连通情况是否一致只要看连通块个数即可,因为枚举到的连通情况肯定是全选了的情况的子集,只要个数一样就一定等价。
#include <iostream>#include <cstdio>#include <cstring>#include <algorithm>#include <cmath>#define MAXN 110#define MAXM 1010#define mod 31011using namespace std;int n,m,cnt,sum;int father[MAXM];int father2[MAXM];int ans=1;struct node{ int to,val,head;}e[MAXM];void build(int x,int y,int z){ cnt++; e[cnt].head=x; e[cnt].to=y; e[cnt].val=z;}bool cmp(node aa,node bb){ return aa.val<bb.val;}int getfather(int x){ if(x==father[x]) return x; else father[x]=getfather(father[x]); return father[x];}int getfather2(int x){ if(x==father2[x]) return x; return getfather2(father2[x]);}int dfs(int l,int r,int num){ if(!num) return 1; if(r<l) return 0; int fa,fb,cur=0; cur=dfs(l+1,r,num); fa=getfather2(e[l].head); fb=getfather2(e[l].to); if (fa!=fb) { father2[fa]=fb; cur+=dfs(l+1,r,num-1); father2[fa]=fa; } return cur;}void init(){ int x,y,z; for(int i=1;i<=m;i++) { scanf("%d%d%d",&x,&y,&z); build(x,y,z); } for(int i=1;i<=n;i++) { father[i]=i;father2[i]=i; } sort(e+1,e+1+m,cmp); int num=0; int sum=0,tmp=0,l=0,r; for(int i=1;i<=m+1;i++) { if(tmp!=e[i].val) { tmp=e[i].val; r=i-1; if(i!=1) ans=(ans*=dfs(l,r,sum))%mod; sum=0; l=i; memcpy(father2,father,sizeof father2); } int r1=getfather(e[i].head); int r2=getfather(e[i].to); if(r1!=r2) { father[r1]=r2; sum++; num++; } } if(num==n-1) printf("%d\n",ans); else printf("0\n");}int main(){ scanf("%d%d",&n,&m); init(); return 0;}
0 0
- bzoj1016: [JSOI2008]最小生成树计数 MST+DFS
- MST——BZOJ1016 [JSOI2008]最小生成树计数
- 【bzoj1016】【JSOI2008】【最小生成树计数】【dfs+最小生成树】
- 【BZOJ1016】【JSOI2008】最小生成树计数 kruskal+dfs
- [BZOJ1016]JSOI2008最小生成树计数 |kruskal|乘法原理|dfs
- 【Kruskal+DFS】BZOJ1016(JSOI2008)[最小生成树计数]题解
- bzoj1016 [JSOI2008]最小生成树计数(kruskal+dfs+乘法原理)
- 【BZOJ1016】[JSOI2008]最小生成树计数
- BZOJ1016 [JSOI2008]最小生成树计数
- BZOJ1016 && JSOI2008] 最小生成树计数
- bzoj1016: [JSOI2008]最小生成树计数
- 【JSOI2008】【BZOJ1016】最小生成树计数
- jsoi2008最小生成树计数bzoj1016
- bzoj1016: [JSOI2008]最小生成树计数
- [BZOJ1016][JSOI2008]最小生成树计数
- BZOJ1016 [JSOI2008]最小生成树计数
- 【JSOI2008】 bzoj1016 最小生成树计数
- BZOJ1016: [JSOI2008]最小生成树计数 Kruskal
- 又一次想写博客了
- 第六周作业——1.利用哈夫曼编码英文字母表,2哈夫曼编码实现
- C++回调机制实现
- IO之阻塞与非阻塞比较
- 第7周作业3——最长递增子序列
- bzoj1016: [JSOI2008]最小生成树计数 MST+DFS
- 几款游戏引擎技术对比
- DefaultIfEmpty and Left Outer Join
- 浙大PAT考试1009~1012(1010是个神题。。)
- 第1次实验——NPC问题(回溯算法、聚类分析)
- 第2次实验——算法基本功 与 综合思考
- Notification的一些知识
- 常用Unicode函数
- LINQ to SQL语句之Join