您的位置:首页 > Web前端 > JavaScript

[BZOJ]1016: [JSOI2008]最小生成树计数

2017-05-30 20:47 435 查看
#include <cstdio>
#include <algorithm>
using namespace std;
#define mod 31011
inline char tc(void)
{
static char fl[10000],*A=fl,*B=fl;
return A==B&&(B=(A=fl)+fread(fl,1,10000,stdin),A==B)?EOF:*A++;
}
inline int read(void)
{
int a=0,f=1;static char c;
while((c=tc())<'0'||c>'9')c=='-'?f=-1:0;
while(c>='0'&&c<='9')
a=a*10+c-'0',c=tc();
return a*f;
}
int n,m,ans=1,cnt,tot,fa[101],sum;
struct Edge
{
int from,to,cost;
inline bool operator <(const Edge&b) const
{
return cost<b.cost;
}
}edge[1001];
struct datw
{
int l,r,cnt;
}data[1001];

inline int gf(int x)
{
while(fa[x]!=x)
x=fa[x];
return x;
}

void dfs(int i,int l,int now)
{
if(l==data[i].r+1)
{
if(now==data[i].cnt)
++sum;
return ;
}
int x=gf(edge[l].from),y=gf(edge[l].to);
if(x!=y)
{
fa[x]=y;
dfs(i,l+1,now+1);
fa[x]=x,fa[y]=y;
}
dfs(i,l+1,now);
return ;
}

int main(void)
{
register int i,j,x,y;
n=read(),m=read();
for (i=1;i<=n;++i)
fa[i]=i;
for (i=1;i<=m;++i)
edge[i].from=read(),edge[i].to=read(),edge[i].cost=read();
sort(edge+1,edge+m+1),edge[0].cost=-1;
for (i=1;i<=m;++i)
{
if(edge[i].cost!=edge[i-1].cost)
data[cnt].r=i-1,data[++cnt].l=i;
x=gf(edge[i].from),y=gf(edge[i].to);
if(x!=y)
++data[cnt].cnt,fa[x]=y,++tot;
}
data[cnt].r=m;
if(tot!=n-1)
{
puts("0");
return 0;
}
for (i=1;i<=n;++i)
fa[i]=i;
for (i=1;i<=cnt;++i)
{
sum=0,dfs(i,data[i].l,0),ans=ans*sum%mod;
for (j=data[i].l;j<=data[i].r;++j)
{
x=gf(edge[j].from),y=gf(edge[j].to);
if(x!=y)
fa[x]=y;
}
}
printf("%d",ans);
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: