BZOJ 1016 JSOI2008 最小生成树计数 Kruskal
2014-10-18 15:58
435 查看
题目大意:给定一个无向图,求最小生成树的方案数
首先对于一个无向图的最小生成树,每种边权的边的数量是一定的
首先我们先跑一遍Kruskal,求出最小生成树上每种边权的出现次数
然后对于每种出现在最小生成树上的边权,我们从小到大处理
对于每种边权,我们枚举这种边权的边有多少种方案可以加进最小生成树上而不形成环 这个用状压处理
ans乘上这个值 然后把这种边权连接的所有联通块缩点
注意最小生成树不存在时输出0
首先对于一个无向图的最小生成树,每种边权的边的数量是一定的
首先我们先跑一遍Kruskal,求出最小生成树上每种边权的出现次数
然后对于每种出现在最小生成树上的边权,我们从小到大处理
对于每种边权,我们枚举这种边权的边有多少种方案可以加进最小生成树上而不形成环 这个用状压处理
ans乘上这个值 然后把这种边权连接的所有联通块缩点
注意最小生成树不存在时输出0
#include<map> #include<cstdio> #include<cstring> #include<iostream> #include<algorithm> #define M 1010 #define Mo 31011 using namespace std; struct edge{ int x,y,f; bool operator < (const edge &z) const { return f < z.f ; } }edges[M]; int n,m,ans=1,fa[110]; int digit[M+100]; map<int,int>a; int Find(int x) { if(!fa[x]||fa[x]==x) return fa[x]=x; return fa[x]=Find(fa[x]); } void Kruskal() { int i,cnt=0; memset(fa,0,sizeof fa); for(i=1;i<=m;i++) { int x=Find(edges[i].x),y=Find(edges[i].y); if(x==y) continue; fa[x]=y; cnt++;a[edges[i].f]++; } if(cnt!=n-1) { puts("0"); exit(0); } } int Deal(int x) { int i,j,y,re=0,cnt=a[edges[x].f]; for(y=x;edges[y].f==edges[y+1].f;y++); for(i=0;i<1<<y-x+1;i++) if(digit[i]==cnt) { int temp=i; memset(fa,0,sizeof fa); for(j=x;temp;temp>>=1,j++) if(temp&1) { int xx=Find(edges[j].x); int yy=Find(edges[j].y); if(xx==yy) break; fa[xx]=yy; } if(!temp) ++re; } ans*=re,ans%=Mo; memset(fa,0,sizeof fa); for(i=x;i<=y;i++) { int xx=Find(edges[i].x),yy=Find(edges[i].y); if(xx==yy) continue; fa[xx]=yy; } for(i=y+1;i<=m;i++) edges[i].x=Find(edges[i].x),edges[i].y=Find(edges[i].y); return y; } int main() { int i; for(i=0;i<1<<10;i++) digit[i]=digit[i>>1]+(i&1); cin>>n>>m; for(i=1;i<=m;i++) scanf("%d%d%d",&edges[i].x,&edges[i].y,&edges[i].f); sort(edges+1,edges+m+1); Kruskal(); for(i=1;i<=m;i++) if(a[edges[i].f]) i=Deal(i); cout<<ans<<endl; return 0; }
相关文章推荐
- 【BZOJ1016】【JSOI2008】最小生成树计数 kruskal+dfs
- 【BZOJ1016】【JSOI2008】最小生成树计数 & 【BZOJ1543】生成树计数 (kruskal+matrix_tree定理)
- 【kruskal】【dfs】【JSOI 2008】【bzoj 1016】最小生成树计数
- BZOJ 1016: [JSOI2008]最小生成树计数( kruskal + dfs )
- [bzoj 1016] [JSOI2008]最小生成树计数:Kruskal,枚举
- [BZOJ1016][JSOI2008]最小生成树计数(Kruskal+计数)
- 【Kruskal+dfs】BZOJ1016- [JSOI2008]最小生成树计数
- BZOJ.1016.[JSOI2008]最小生成树计数(Matrix Tree定理 Kruskal)
- bzoj1016: [JSOI2008]最小生成树计数(kruskal+dfs)
- [BZOJ 1016][JSOI2008]最小生成树计数(Kruskal)
- 【BZOJ】1016: [JSOI2008]最小生成树计数(kruskal+特殊的技巧)
- [BZOJ1016]JSOI2008最小生成树计数 |kruskal|乘法原理|dfs
- [bzoj1016][JSOI2008]最小生成树计数 (Kruskal + Matrix Tree 定理)
- BZOJ 题目1016: [JSOI2008]最小生成树计数(Kruskal+Matrix_Tree)
- BZOJ 1016: [JSOI2008]最小生成树计数 kruskal dfs
- BZOJ 1016 [JSOI2008]最小生成树计数 Kruskal Matrix-Tree定理
- BZOJ1016([JSOI2008]最小生成树计数)Kruskal+Matrix_Tree定理
- BZOJ 1016: [JSOI2008]最小生成树计数
- BZOJ 1016 JSOI 2008 最小生成树计数 Kruskal+搜索
- 【JSOI 2008】【BZOJ 1016】最小生成数计数