bzoj 1016: [JSOI2008]最小生成树计数
2017-12-14 21:41
441 查看
Description
现在给出了一个简单无向加权图。你不满足于求出这个图的最小生成树,而希望知道这个图中有多少个不同的最小生成树。(如果两颗最小生成树中至少有一条边不同,则这两个最小生成树就是不同的)。由于不同的最小生
成树可能很多,所以你只需要输出方案数对31011的模就可以了。
solution
正解:kruskal+枚举我们需要明白:对于所有的最小生成树满足:1.相同边权的边数相同。2.相同边权的边合并的点集也是一定的.
两个结论可以一起证明:边数显然不可能增加,不然在做第一次kruskal的时候肯定会被加入,如果边数还可以减少,那么有一些点肯定还没有被合并,那么合并可以使得边数+1.
所以我们枚举边权,因为相同边权的边不超过10,所以对每一种边权枚举,方案相乘即可
#include <algorithm> #include <iostream> #include <cstdlib> #include <cstring> #include <cstdio> #include <cmath> #define RG register #define il inline #define iter iterator #define Max(a,b) ((a)>(b)?(a):(b)) #define Min(a,b) ((a)<(b)?(a):(b)) using namespace std; typedef long long ll; const int N=10005,mod=31011; int fa ,n,m,t=0; struct node{ int x,y,z; bool operator <(const node &pr)const{return z<pr.z;} }e ; inline int find(int x){return fa[x]==x?x:find(fa[x]);} int l ,r ,v ; bool priwork(){ int x,y,cnt=0; for(int i=1;i<=m;i++){ if(e[i].z!=e[i-1].z)t++,l[t]=i; r[t]=i; x=e[i].x;y=e[i].y; if(find(x)==find(y))continue; fa[find(y)]=find(x); cnt++;v[t]++; } if(cnt!=n-1)return false; for(int i=1;i<=n;i++) for(int j=i+1;j<=n;j++) if(find(i)!=find(j))return false; return true; } int cnt=0; inline void dfs(int i,int x,int sum){ if(x>r[i]){if(sum==v[i])cnt++;return ;} dfs(i,x+1,sum); int a=find(e[x].x),b=find(e[x].y); if(a!=b){ fa[b]=a; dfs(i,x+1,sum+1); fa[b]=b;fa[a]=a; } } void work() { cin>>n>>m; for(int i=1;i<=m;i++)cin>>e[i].x>>e[i].y>>e[i].z; for(int i=1;i<=n;i++)fa[i]=i; sort(e+1,e+m+1); if(!priwork()){puts("0");return ;} int ans=1,x,y; for(int i=1;i<=n;i++)fa[i]=i; for(int i=1;i<=t;i++){ cnt=0; dfs(i,l[i],0); ans*=cnt;if(ans>=mod)ans%=mod; for(int j=l[i];j<=r[i];j++){ x=e[j].x;y=e[j].y; if(find(x)==find(y))continue; fa[find(y)]=find(x); } } cout<<ans<<endl; } int main() { work(); return 0; }
相关文章推荐
- 【BZOJ 1016】【JSOI 2008】最小生成树计数
- bzoj1016: [JSOI2008]最小生成树计数 MST+DFS
- 【BZOJ 1016】【JSOI 2008】最小生成树计数
- bzoj1016: [JSOI2008]最小生成树计数
- BZoj 1016: [JSOI2008]最小生成树计数【最小生成树】
- [BZOJ1016][JSOI2008]最小生成树计数-并查集-状态压缩-最小生成树
- [bzoj1016][JSOI2008]最小生成树计数
- 【bzoj 1016】[JSOI2008]最小生成树计数 脑残是病
- [bzoj1016][JSOI2008]最小生成树计数【MST】【暴力】
- BZOJ 1016 [JSOI2008]最小生成树计数
- [生成树 MatrixTree定理] BZOJ 1016 [JSOI2008]最小生成树计数
- BZOJ1016 [JSOI2008]最小生成树计数
- bzoj 1016: [JSOI2008]最小生成树计数
- bzoj 1016: [JSOI2008]最小生成树计数
- 【JSOI2008】【BZOJ1016】最小生成树计数
- BZOJ 1016 JSOI 2008 巨额奖金 最小生成树计数
- 【JSOI 2008】【BZOJ 1016】最小生成数计数
- 【BZOJ1016】[JSOI2008]最小生成树计数【最小生成树】【搜索】
- BZOJ_1016_[JSOI2008]_最小生成树计数_(dfs+乘法原理)
- BZOJ 题目1016: [JSOI2008]最小生成树计数(Kruskal+Matrix_Tree)