现在给出了一个简单无向加权图。你不满足于求出这个图的最小生成树,而希望知道这个图中有多少个不同的最小生成树。(如果两颗最小生成树中至少有一条边不同,则这两个最小生成树就是不同的)。由于不同的最小生成树可能很多,所以你只需要输出方案数对31011的模就可以了。

跑一遍克鲁斯卡尔,记录每种权值的边有多少条,然后状压枚举满足条件的所有边乘到答案中即可

/**************************************************************
Problem: 1016
User: walfy
Language: C++
Result: Accepted
Time:68 ms
Memory:1452 kb
****************************************************************/ //#pragma comment(linker, "/stack:200000000")
//#pragma GCC optimize("Ofast,no-stack-protector")
//#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
//#pragma GCC optimize("unroll-loops")
#include<bits/stdc++.h>
#define fi first
#define se second
#define mp make_pair
#define pb push_back
#define pi acos(-1.0)
#define ll long long
#define vi vector<int>
#define mod 1000000007
#define C 0.5772156649
#define ls l,m,rt<<1
#define rs m+1,r,rt<<1|1
#define pil pair<int,ll>
#define pli pair<ll,int>
#define pii pair<int,int>
#define cd complex<double>
#define ull unsigned long long
#define base 1000000000000000000
#define fio ios::sync_with_stdio(false);cin.tie(0) using namespace std; const double g=10.0,eps=1e-;
const int N=+,maxn=+,inf=0x3f3f3f3f,INF=0x3f3f3f3f3f3f3f3f; struct edge{
int u,v,c;
bool operator<(const edge &rhs)const{
return c<rhs.c;
}
}e[N];
map<int,int>ans,id;
vector<pii>v[N];
int fa[N],prefa[N];
int Find(int x)
{
return fa[x]==x?x:fa[x]=Find(fa[x]);
}
int main()
{
fio;
int n,m;
cin>>n>>m;
for(int i=;i<=n;i++)fa[i]=i;
int cnt=;
for(int i=;i<m;i++)
{
int a,b,c;
cin>>a>>b>>c;
e[i]={a,b,c};
}
sort(e,e+m);
for(int i=;i<m;i++)
{
if(!id[e[i].c])id[e[i].c]=++cnt;
v[id[e[i].c]].pb(mp(e[i].u,e[i].v));
int x=e[i].u,y=e[i].v;
int fx=Find(x),fy=Find(y);
if(fx!=fy)fa[fx]=fy,ans[e[i].c]++;
}
for(int i=;i<=n;i++)
if(Find(i)!=Find(i-))
{
cout<<<<"\n";
return ;
}
for(int i=;i<=n;i++)fa[i]=i;
map<int,int>::iterator it=id.begin();
ll res=;
for(;it!=id.end();it++)
{
for(int i=;i<=n;i++)prefa[i]=fa[i];
// for(int i=0;i<v[it->se].size();i++)printf("%d %d %d\n",i,v[it->se][i].fi,v[it->se][i].se);
// puts("");
ll len=v[it->se].size(),go=-,pp=;
for(int i=;i<(<<len);i++)
{
int num=;
for(int j=;j<len;j++)
if((i>>j)&)
num++;
if(num!=ans[it->fi])continue;
else
{ bool ok=;
for(int j=;j<len;j++)
{
if((i>>j)&)
{
int x=v[it->se][j].fi,y=v[it->se][j].se;
int fx=Find(x),fy=Find(y);
if(fx!=fy)fa[fx]=fy;
else ok=;
}
}
if(ok)pp++,go=i;//,printf("%d\n",i);
}
for(int j=;j<=n;j++)fa[j]=prefa[j];
}
// printf("%d\n",pp);
res=(res*pp)%;
if(go==-)continue;
for(int j=;j<len;j++)
{
if((go>>j)&)
{
int x=v[it->se][j].fi,y=v[it->se][j].se;
int fx=Find(x),fy=Find(y);
if(x!=y)fa[fx]=fy;
}
}
}
cout<<res<<"\n";
return ;
}
/***********************
4 6 1 2 1 1 3 1 1 4 1 2 3 2 2 4 1 3 4 3
***********************/

bzo1016: [JSOI2008]最小生成树计数的更多相关文章

  1. bzoj1016 [JSOI2008]最小生成树计数

    1016: [JSOI2008]最小生成树计数 Time Limit: 1 Sec  Memory Limit: 162 MBSubmit: 3517  Solved: 1396[Submit][St ...

  2. BZOJ 1016: [JSOI2008]最小生成树计数( kruskal + dfs )

    不同最小生成树中权值相同的边数量是一定的, 而且他们对连通性的贡献是一样的.对权值相同的边放在一起(至多10), 暴搜他们有多少种方案, 然后乘法原理. ----------------------- ...

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

    1016: [JSOI2008]最小生成树计数 Time Limit: 1 Sec  Memory Limit: 162 MBSubmit: 6200  Solved: 2518[Submit][St ...

  4. 【BZOJ 1016】 1016: [JSOI2008]最小生成树计数 (DFS|矩阵树定理)

    1016: [JSOI2008]最小生成树计数 Description 现在给出了一个简单无向加权图.你不满足于求出这个图的最小生成树,而希望知道这个图中有多少个不同的最小生成树.(如果两颗最小生成树 ...

  5. 【bzoj1016】[JSOI2008]最小生成树计数

    1016: [JSOI2008]最小生成树计数 Time Limit: 1 Sec  Memory Limit: 162 MBSubmit: 4863  Solved: 1973[Submit][St ...

  6. bzoj1016: [JSOI2008]最小生成树计数(kruskal+dfs)

    1016: [JSOI2008]最小生成树计数 题目:传送门 题解: 神题神题%%% 据说最小生成树有两个神奇的定理: 1.权值相等的边在不同方案数中边数相等  就是说如果一种方案中权值为1的边有n条 ...

  7. 【bzoj1016】 JSOI2008—最小生成树计数

    http://www.lydsy.com/JudgeOnline/problem.php?id=1016 (题目链接) 题意 求图的最小生成树计数. Solution %了下题解,发现要写矩阵树,15 ...

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

    最小生成树计数 题目描述 现在给出了一个简单无向加权图.你不满足于求出这个图的最小生成树,而希望知道这个图中有多少个不同的最小生成树.(如果两颗最小生成树中至少有一条边不同,则这两个最小生成树就是不同 ...

  9. 【BZOJ】1016: [JSOI2008]最小生成树计数 深搜+并查集

    最小生成树计数 Description 现在给出了一个简单无向加权图.你不满足于求出这个图的最小生成树,而希望知道这个图中有多少个不同的最小生成树.(如果两颗最小生成树中至少有一条边不同,则这两个最小 ...

随机推荐

  1. CentOS 7 安装vsftpd 服务器

    在CentOS7上安装ftp服务器用于保存服务端上传的图片. 1.CentOS卸载vsftpd的方法 如果服务器上已经安装了vsftpd服务,配置出错需要卸载vsftpd服务. 1.1 查找vsftp ...

  2. MySQL 参数

    I see a lot of people filtering replication with binlog-do-db, binlog-ignore-db, replicate-do-db, an ...

  3. oracle RMAN复制数据库

    列出创建副本数据库的目的 • 选择用于复制数据库的方法 • 使用RMAN 复制数据库 • 使用RMAN 备份复制数据库 • 基于正在运行的实例复制数据库   使用副本数据库 • 使用副本数据库可执行以 ...

  4. XDU 1111

    对于一排n个正方形,有f(n)种方案达成目标,若第n个块是白色,则有f(n-1)种方案,若第n个块是黑色,则第n-1个块必为白色,那么有f(n-2)+n-2种方案. 则f(n)=f(n-1)+f(n- ...

  5. Codeforces Round #403 (Div. 2, based on Technocup 2017 Finals) A. Andryusha and Socks

    地址:http://codeforces.com/contest/782/problem/A 题目: A. Andryusha and Socks time limit per test 2 seco ...

  6. CodeForces - 662C Binary Table (FWT)

    题意:给一个N*M的0-1矩阵,可以进行若干次操作,每次操作将一行或一列的0和1反转,求最后能得到的最少的1的个数. 分析:本题可用FWT求解. 因为其0-1反转的特殊性且\(N\leq20\),将每 ...

  7. sgu 101 Domino 解题报告及测试数据

    101. Domino time limit per test: 0.25 sec. memory limit per test: 4096 KB 题解: 求多米诺骨牌按照一定方式放置能否使相邻的位置 ...

  8. 理解android分辨率限定符 layout-sw360dp

    首先,我们来看看单位dp是怎么一回事,dp是一种单位,使用它,你可以在高.低分辨率上获得一样的空间表现,也就是说,它是像素无关的. dp计算公式:160*pix/ppi(pix是你要计算的高度或者宽度 ...

  9. Hadoop集群的各部分常用端口

    hadoop集群的各部分一般都会使用到多个端口,有些是daemon之间进行交互之用,有些是用于RPC访问以及HTTP访问.而随着hadoop周边组件的增多,完全记不住哪个端口对应哪个应用,特收集记录如 ...

  10. AndroidStudio 使用AIDL

    http://blog.csdn.net/ducklikejava/article/details/51559244 Android Studio中写的一个AIDL的小DEMO. 步骤很繁琐,本来不准 ...