bzoj1016
来源:互联网 发布:淘宝没发货退款要多久 编辑:程序博客网 时间:2024/06/05 09:42
噗~ 其实目前的想法的话 是跟着Aekdycoin神的脚步 开始坚持把bzoj继续刷下去·· 其实我并不知道自己还能坚持多久了啦不过凡事都要尽力而为 所以只是记下一些稍微重要的题目,用来作为一个类似备忘录 的作用吧!
题目的话在bzoj上面:http://www.lydsy.com/JudgeOnline/problem.php?id=1016
大概的题意就是:求一个图的最小生成树个数~
这里要用到主要的一个东西就是··~
1、边权相等的边的个数一定。
2、做完边权为w的所有边时,图的连通性相同。
因此 可以通过这个性质先求出该图的最小生成树··~ 记录下各个边权的个数,之后的话因为条件2,对边权大小进行枚举~
将求出的最小生成树中除了枚举边权以外的边全部连上~ 并查集缩点
之后从原图中找出与枚举边权相同的边~ 对于缩点之后的图进行连边~ 再用一次拉普拉斯矩阵 求生成树个数就可以啦
关于拉普拉斯矩阵:http://en.wikipedia.org/wiki/Laplacian_matrix
简单地说就是 拉普拉斯矩阵=度数矩阵-邻接矩阵 对于该矩阵去掉一行一列求其行列式的值 就是生成树个数
对于每个边权都求出等价连通性的边连法 乘法定理走起~ 求出最终答案!
我只是按自己的理解来写了啦不过应该是实现方法比较挫 导致写了好长 代码风格是时候改一下啦看到人家写的2000B不到的代码各种羡慕Otz
//============================================================================// Name : bzoj1016.cpp// Author : // Version :// Copyright : Your copyright notice// Description : Hello World in C++, Ansi-style//============================================================================#include <iostream>#include<string>#include<cstdio>#include<cstring>#include<algorithm>#define MOD 31011#define N 105using namespace std;struct node{int ui,vi,val;};node edge[2005];int cmp(node a,node b){if (a.val!=b.val)return (a.val<b.val);return (a.ui<b.ui);}int cnt;int fah[105];int que[2005];int cntq;int getfather(int x){if (x!=fah[x])fah[x]=getfather(fah[x]);return (fah[x]);}int det(int a[][N],int n)//生成树计数:Matrix-Tree定理{ for(int i=0; i<n; i++) for(int j=0; j<n; j++) a[i][j]%=MOD; int ret=1; for(int i=1; i<n; i++) { for(int j=i+1; j<n; j++) while(a[j][i]) { int t=a[i][i]/a[j][i]; for(int k=i; k<n; k++) a[i][k]=(a[i][k]-a[j][k]*t)%MOD; for(int k=i; k<n; k++) swap(a[i][k],a[j][k]); ret=-ret; } if(a[i][i]==0) return 0; ret=ret*a[i][i]%MOD; } if(ret<0) ret=-ret; return (ret+MOD)%MOD;}int bin_sl(int now){int b_l=0,b_r=cnt-1;while (b_r-b_l>1){int b_mid=(b_l+b_r)>>1;if (edge[b_mid].val>=now)b_r=b_mid;elseb_l=b_mid;}if (edge[b_l].val==now) return(b_l);return (b_r);}int bin_sr(int now){int b_l=0,b_r=cnt-1;while (b_r-b_l>1){int b_mid=(b_l+b_r)>>1;if (edge[b_mid].val>now)b_r=b_mid;elseb_l=b_mid;}if (edge[b_r].val==now) return (b_r);return (b_l);}int n,m;int main() {scanf("%d%d",&n,&m);cnt=-1;for (int i=0;i<m;i++){cnt++;scanf("%d%d%d",&edge[cnt].ui,&edge[cnt].vi,&edge[cnt].val);edge[cnt].ui--;edge[cnt].vi--;cnt++;edge[cnt].ui=edge[cnt-1].ui;edge[cnt].vi=edge[cnt-1].vi;edge[cnt].val=edge[cnt-1].val;}cnt++;sort(edge,edge+cnt,cmp);for (int i=0;i<n;i++) fah[i]=i;cntq=0;for (int i=0;i<cnt;i++){int nowx,nowy;nowx=getfather(edge[i].ui);nowy=getfather(edge[i].vi);if (nowx!=nowy){fah[nowx]=nowy;que[cntq++]=i;}}int li,ri;int ans=1;li=ri=0;//cout<<cntq<<endl;/*for (int i=0;i<cntq;i++)printf("node1-->%d node2-->%d nodeval-->%d\n",edge[que[i]].ui,edge[que[i]].vi,edge[que[i]].val);*/while (li<cntq){while (ri<cntq && edge[que[li]].val==edge[que[ri]].val) ri++;ri--;//cout<<"ri="<<ri<<endl;for (int i=0;i<n;i++) fah[i]=i;for (int i=0;i<cntq;i++)if (i<li || i>ri){int nowx,nowy;nowx=getfather(edge[que[i]].ui);nowy=getfather(edge[que[i]].vi);fah[nowx]=nowy;}int vised[105];int cntn=0;memset(vised,-1,sizeof(vised));for (int i=0;i<n;i++){int nowx=getfather(i);if (vised[nowx]==-1)vised[nowx]=cntn++;}int lf=bin_sl(edge[que[li]].val);int rf=bin_sr(edge[que[li]].val);int gra[N][N];memset(gra,0,sizeof(gra));for (int i=lf;i<=rf;i++){int nowx,nowy;nowx=getfather(edge[i].ui);nowy=getfather(edge[i].vi);if (nowx!=nowy){gra[vised[nowx]][vised[nowx]]++;gra[vised[nowy]][vised[nowy]]++;gra[vised[nowx]][vised[nowy]]--;gra[vised[nowy]][vised[nowx]]--;}}for (int i=0;i<cntn;i++){for (int j=0;j<cntn;j++)gra[i][j]/=2;}ans=ans*det(gra,cntn);ans%=MOD;ri=li=ri+1;//cout<<"li="<<li<<endl;}printf("%d\n",ans);return 0;}
0 0
- bzoj1016
- bzoj1016
- BZOJ1016
- bzoj1016【最小生成树计数】
- bzoj1016 最小生成树计数
- 【BZOJ1016】[JSOI2008]最小生成树计数
- BZOJ1016 [JSOI2008]最小生成树计数
- BZOJ1016 && JSOI2008] 最小生成树计数
- bzoj1016: [JSOI2008]最小生成树计数
- 【JSOI2008】【BZOJ1016】最小生成树计数
- jsoi2008最小生成树计数bzoj1016
- bzoj1016: [JSOI2008]最小生成树计数
- [BZOJ1016][JSOI2008]最小生成树计数
- BZOJ1016 [JSOI2008]最小生成树计数
- 【JSOI2008】 bzoj1016 最小生成树计数
- BZOJ1016: [JSOI2008]最小生成树计数 Kruskal
- 【bzoj1016】 JSOI2008—最小生成树计数
- bzoj1016: [JSOI2008]最小生成树计数
- (模板)c++ 大数(正数加减乘除)
- 操作系统内存管理
- 排序算法之直接插入排序
- IOS开发------图片浏览器之UIImageView中的animation
- linux 忘记非root用户密码
- bzoj1016
- Java中abstract class 和 interface 的解释和他们的异同点(转)
- (模板)JAVA 大数的使用
- zend studio 创建php项目
- (模板)AC自动机
- Spring中@Autowired注解、@Resource注解的区别
- 购买PG霜,请认准官方网站
- 【记录吧】2014.10.13
- (模板)KMP