码迷,mamicode.com
首页 > Web开发 > 详细

BZOJ 1016 JSOI2008 最小生成树计数 Kruskal

时间:2014-10-18 17:02:36      阅读:255      评论:0      收藏:0      [点我收藏+]

标签:bzoj   bzoj1016   kruskal   

题目大意:给定一个无向图,求最小生成树的方案数

首先对于一个无向图的最小生成树,每种边权的边的数量是一定的

首先我们先跑一遍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;
}


BZOJ 1016 JSOI2008 最小生成树计数 Kruskal

标签:bzoj   bzoj1016   kruskal   

原文地址:http://blog.csdn.net/popoqqq/article/details/40211987

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!