【JSOI 2008】【BZOJ 1016】最小生成数计数
来源:互联网 发布:软件测试人员招聘 编辑:程序博客网 时间:2024/05/22 03:16
这题题目中有一个很显眼的提示,每种权值的边不会超过10条,这提示我们可以采用些暴力方法。
首先在每个最小生成树中有两个结论:
1、每种权值的边数相等。
2、每种权值所选边构建后图的联通形态相同。
1比较好理解,若1不成立,则最小生成树总权值不固定。
2可以通过Kruskal算法流程来理解。
code:
#include<iostream>#include<cstdio>#include<cstring>#include<algorithm>using namespace std;struct hq{ int sum; int num[1001];}stack[1001],tot[1001];struct hp{ int u,v,w;}a[1001];int father[1001],now[1001],fathernow[1001],fatherlast[1001];int b[1001],n,m,size,sum=0,t=0,ans=1;int cmp(const hp &a,const hp &b){ if (a.w<b.w) return 1; else return 0;}int findnow(int x){ if (x!=fathernow[x]) fathernow[x]=findnow(fathernow[x]); return fathernow[x];}int find(int x){ if (x!=father[x]) father[x]=find(father[x]); return father[x];}bool judge(){ int i,r1,r2; bool f=false; for (i=1;i<=n;++i) fathernow[i]=fatherlast[i]; for (i=1;i<=t;++i) { r1=findnow(a[now[i]].u); r2=findnow(a[now[i]].v); if (r1<r2) fathernow[r1]=fathernow[r2]; else { if (r2<r1) fathernow[r2]=fathernow[r1]; else f=true; } } for (i=1;i<=n;++i) findnow(i),find(i); for (i=1;i<=n;++i) if (fathernow[i]!=father[i]) f=true; for (i=1;i<=n;++i) fathernow[i]=fatherlast[i]; if (f) return false; else return true;}void work(int wgt,int i,int last){ int j; if (i==tot[wgt].sum+1) { if (judge()) sum=(sum+1)%31011; return; } for (j=last+1;j<=stack[wgt].sum;++j) { now[++t]=stack[wgt].num[j]; work(wgt,i+1,j); --t; }}int main(){ int i,r1,r2,j,k=0,wgt=0; scanf("%d%d",&n,&m); for (i=1;i<=m;++i) { scanf("%d%d%d",&a[i].u,&a[i].v,&a[i].w); b[i]=a[i].w; } sort(b+1,b+m+1); size=unique(b+1,+b+m+1)-b-1; for (i=1;i<=m;++i) a[i].w=upper_bound(b+1,b+size+1,a[i].w)-b-1; sort(a+1,a+m+1,cmp); for (i=1;i<=m;++i) stack[a[i].w].num[++stack[a[i].w].sum]=i; for (i=1;i<=n;++i) father[i]=i; for (i=1;i<=m;++i) { r1=find(a[i].u); r2=find(a[i].v); if (r1!=r2) { tot[a[i].w].num[++tot[a[i].w].sum]=i; wgt+=a[i].w; father[r1]=r2; k++; size=a[i].w; } if (k==n-1) break; } if (k!=n-1) printf("0\n"); else { for (i=1;i<=n;++i) father[i]=fatherlast[i]=i; for (i=1;i<=size;++i) { for (j=1;j<=tot[i].sum;++j) { r1=find(a[tot[i].num[j]].u); r2=find(a[tot[i].num[j]].v); if (r1<r2) father[r1]=father[r2]; if (r2<r1) father[r2]=father[r1]; } memset(now,0,sizeof(now)); t=0; sum=0; work(i,1,0); ans=(ans*sum)%31011; for (j=1;j<=n;++j) fatherlast[j]=father[j]; } printf("%d\n",ans); }}
1 1
- 【JSOI 2008】【BZOJ 1016】最小生成数计数
- 【kruskal】【dfs】【JSOI 2008】【bzoj 1016】最小生成树计数
- 【BZOJ 1016】【JSOI 2008】最小生成树计数
- BZOJ 1016 JSOI 2008 巨额奖金 最小生成树计数
- BZOJ 1016 JSOI 2008 最小生成树计数 Kruskal+搜索
- 【BZOJ 1016】 [JSOI2008]最小生成树计数
- BZOJ 1016: [JSOI2008]最小生成树计数
- BZOJ 1016 最小生成树计数 Kruskal
- 最小生成树计数 bzoj 1016
- BZOJ 1016 [JSOI2008]最小生成树计数
- BZOJ 1016,1543 最小生成树计数
- BZOJ 1016, 最小生成树计数
- BZOJ 1016 [JSOI2008] 最小生成树计数
- [BZOJ]1016: [JSOI2008]最小生成树计数
- bzoj 1016: [JSOI2008]最小生成树计数
- bzoj 1016: [JSOI2008]最小生成树计数
- BZOJ 1016 最小生成树计数 暴力
- bzoj 1016: [JSOI2008]最小生成树计数
- 树的子结构
- 四则运算程序
- 动态修改script标签中的src属性存在的问题
- 【教材】用OllyDbg找出Agth提取GAL文本的特殊码(详细新人版)
- Delphi应用程序的调试(连载,瓢虫原著)
- 【JSOI 2008】【BZOJ 1016】最小生成数计数
- Cashcard transaction history read software
- Android系统手机端抓包方法(tcpdump)
- Git远程操作详解
- php+MySQL图书管理系统(一)
- An Adaptive Communication Architecture for Wireless Sensor Networks
- Java异常的处理
- iOS - 版面实现记录五
- 归一化