# BZOJ1016 JSOI2008 最小生成树计数

Code:

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <algorithm>
#include <cmath>
#include <cstring>
#include <vector>
#include <set>
#include <map>
#include <ctime>

#define ps system("pause")
#define message printf("*\n")
#define pb push_back
#define X first
#define Y second

using namespace std;

struct node{
int a,b,w;
}edge[2010];

int f[110],use[10010],powe[20];
int cnt,n,m,minnum,ans,cur,res;

int find(int x){
if	(f[x]==x)	return	x;
f[x]=find(f[x]);
return	f[x];
}

bool cmp(node aa,node bb){
return	aa.w<bb.w;
}

void setup(){
int cur=1;
for	(int i=1;i<=m;i++)
if	(edge[i].w!=edge[i+1].w)	edge[i].w=cur++;
else	edge[i].w=cur;
}

int calc(int x){
int v=0;
while	(x){
v+=x&1;
x/=2;
}
return	v;
}

bool check(int x,int sit){
cnt=n;res=edge[x].w*use[edge[x].w];
for	(int i=1;i<=n;i++)	f[i]=i;
for	(int i=x;edge[i].w==edge[x].w;i++){
if	(sit&1){
f[edge[i].a]=find(edge[i].a);
f[edge[i].b]=find(edge[i].b);
if	(f[edge[i].a]!=f[edge[i].b]){
f[f[edge[i].b]]=f[edge[i].a];
--cnt;
}
}
sit/=2;
}
for	(int i=1;i<=m && cnt>1;i++){
if	(edge[i].w==edge[x].w)	continue;
f[edge[i].a]=find(edge[i].a);
f[edge[i].b]=find(edge[i].b);
if	(f[edge[i].a]==f[edge[i].b])	continue;
f[f[edge[i].b]]=f[edge[i].a];
res+=edge[i].w;
if	(--cnt==1)	break;
}
return	(cnt==1 && res==minnum);
}

int main(){
scanf("%d%d",&n,&m);
for	(int i=1;i<=m;i++)
scanf("%d%d%d",&edge[i].a,&edge[i].b,&edge[i].w);
sort(edge+1,edge+m+1,cmp);
setup();
cnt=n;minnum=0;
for	(int i=1;i<=n;i++)	f[i]=i;
for	(int i=1;i<=m && cnt>1;i++){
f[edge[i].a]=find(edge[i].a);
f[edge[i].b]=find(edge[i].b);
if	(f[edge[i].a]==f[edge[i].b])	continue;
f[f[edge[i].b]]=f[edge[i].a];
use[edge[i].w]++;
minnum+=edge[i].w;
if	(--cnt==1)	break;
}
if	(cnt!=1){
printf("0\n");
return	0;
}
ans=1;powe[0]=1;
for	(int i=1;i<=10;i++)	powe[i]=powe[i-1]*2;
for	(int i=1;i<=m;){
int j=i+1;
while	(edge[i].w==edge[j].w)	j++;
if	(use[edge[i].w]){
cur=0;
for	(int sit=0;sit<powe[j-i];sit++)
if	(calc(sit)==use[edge[i].w] && check(i,sit))	cur++;
ans=ans*cur%31011;
}
i=j;
}
printf("%d\n",ans);
return	0;
}


posted @ 2013-02-06 20:42  JS_Shining  阅读(1635)  评论(0编辑  收藏