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

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

2017-08-12 08:40 267 查看
http://www.lydsy.com/JudgeOnline/problem.php?id=1016

题意:



思路:

一个无向图所有的最小生成树中某种权值的边的数目均相同。

引用一篇大牛的证明:

我们证明以下定理:一个无向图所有的最小生成树中某种权值的边的数目均相同。

开始时,每个点单独构成一个集合。

首先只考虑权值最小的边,将它们全部添加进图中,并去掉环,由于是全部尝试添加,那么只要是用这种权值的边能够连通的点,最终就一定能在一个集合中。

那么不管添加的是哪些边,最终形成的集合数都是一定的,且集合的划分情况一定相同。那么真正添加的边数也是相同的。因为每添加一条边集合的数目便减少1.

那么权值第二小的边呢?我们将之间得到的集合每个集合都缩为一个点,那么权值第二小的边就变成了当前权值最小的边,也有上述的结论。

因此每个阶段,添加的边数都是相同的。我们以权值划分阶段,那么也就意味着某种权值的边的数目是完全相同的。

所以先用克鲁斯卡尔算法计算一遍最小生成树,统计每一权值的边组需要加几条边,最后暴搜,乘法原理相乘即可。注意,要判断无法连通的情况。

#include<iostream>
#include<algorithm>
#include<cstring>
#include<cstdio>
#include<sstream>
#include<vector>
#include<stack>
#include<queue>
#include<cmath>
#include<map>
#include<set>
using namespace std;
typedef long long ll;
typedef pair<int,ll> pll;
const int INF = 0x3f3f3f3f;
const int maxn=10000+5;
const int mod=31011;

struct node
{
int u,v,w;
}e[10*maxn];

struct node2
{
int l,r;
int c;
}a[maxn];

int n, m;
int sum;
int cnt,tot;
int p[maxn];

bool cmp(node a, node b)
{
return a.w<b.w;
}

int find(int x)
{
return x==p[x]?x:find(p[x]);
}

void dfs(int cur, int num ,int pos)
{
if(pos>a[cur].r)
{
if(num==a[cur].c) sum++;
return;
}
int x=find(e[pos].u);
int y=find(e[pos].v);
if(x!=y)
{
p[x]=y;
dfs(cur,num+1,pos+1);
p[x]=x;
}
dfs(cur,num,pos+1);
}

int main()
{
//freopen("in.txt","r",stdin);
while(~scanf("%d%d",&n,&m))
{
for(int i=1;i<=n;i++) p[i]=i;
for(int i=1;i<=m;i++)
scanf("%d%d%d",&e[i].u,&e[i].v,&e[i].w);

sort(e+1,e+m+1,cmp);
cnt=0; tot=0;
for(int i=1;i<=m;i++)
{
if(e[i].w!=e[i-1].w)
{
a[++cnt].l=i;
a[cnt-1].r=i-1;
a[cnt].c=0;
}
int x=find(e[i].u);
int y=find(e[i].v);
if(x!=y)
{
p[x]=y;
a[cnt].c++;
tot++;
}
}
a[cnt].r=m;

if(tot!=n-1)  //连不起来的情况
{
printf("0\n");
continue;
}

for(int i=1;i<=n;i++)   p[i]=i;
int ans=1;
for(int i=1;i<=cnt;i++)
{
sum=0;
dfs(i,0,a[i].l);
ans=(ans*sum)%mod;
for(int j=a[i].l;j<=a[i].r;j++)
{
int x=find(e[j].u);
int y=find(e[j].v);
if(x!=y) p[x]=y;
}
}
printf("%d\n",ans);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: