题目链接

  最小生成树有两个性质,两个性质都知道的话这题就变成码农题了。

  1、无论最小生成树长什么样,所有权值的边的数量是不变的。比如我有棵最小生成树有两条权值为2的边四条权值为1的边,那这个图的所有最小生成树都是两条权值为2的边四条权值为1的边。

  2、无论最小生成树长什么样,把边从小到大排序,某一权值的边连完后,联通块一定是固定的。

  这就提示了我们先求一遍最小生成树,得到生成树里每个权值的边都有几条,然后枚举权值,状压当前权值选的边集,看能不能把选出来的这些边都摁进森林里去。如果能的话该权值的连接方案数就+1.

  枚举完之后,因为第二条所以我们直接把所有该权值的边的两个端点合到一个并查集里就好了。

  最后乘法原理得到答案。

  

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cctype>
#include<cstdlib>
#define maxn 10000
#define mod 31011
using namespace std;
inline long long read(){
long long num=,f=;
char ch=getchar();
while(!isdigit(ch)){
if(ch=='-') f=-;
ch=getchar();
}
while(isdigit(ch)){
num=num*+ch-'';
ch=getchar();
}
return num*f;
} struct Edge{
int from,to,val;
}edge[maxn],q[maxn],d[maxn];
bool cmp(Edge a,Edge b){ return a.val<b.val; }
int head[maxn],num;
inline void add(int from,int to,int val){
edge[++num]=(Edge){head[from],to,val};
head[from]=num;
} bool vis[maxn];
int sum[maxn];
int w[maxn];
int size;
struct fus{
int father[maxn];
inline void clear(int n){ for(int i=;i<=n;++i) father[i]=i; }
int find(int x){
if(father[x]!=x) father[x]=find(father[x]);
return father[x];
}
inline void unionn(int x,int y){
x=find(x); y=find(y);
father[y]=x;
}
}c,r,right; inline int getlen(int x){
int ans=;
while(x){
if(x&) ans++;
x>>=;
}
return ans;
} int ans[maxn];
int pre[maxn]; void copy(int x,int *a,int *b){ for(int i=;i<=x;++i) a[i]=b[i];} int main(){
int n=read(),m=read();
for(int i=;i<=m;++i) q[i]=(Edge){read(),read(),read()};
c.clear(n);
sort(q+,q+m+,cmp);
int cnt=,last=,now=;
for(int i=;i<=m;++i){
//离散化
now=q[i].val;
if(q[i].val==last) q[i].val=size;
else q[i].val=++size;
last=now; int from=q[i].from,to=q[i].to;
if(c.find(from)==c.find(to)) continue;
c.unionn(from,to);
vis[q[i].val]=;
sum[q[i].val]++;
cnt++;
if(cnt==n-) break;
}
if(cnt<n-){
printf("");
return ;
}
c.clear(n);
cnt=;
int maxval=;
for(int i=;i<=m;++i)
if(vis[q[i].val]){
d[++cnt]=q[i];
w[q[i].val]++;
maxval=max(maxval,q[i].val);
}
last=;
for(int i=;i<=maxval;++i){
int Max=<<w[d[last+].val];
copy(n,right.father,c.father);
for(int j=;j<Max;++j){
if(getlen(j)!=sum[d[last+].val]) continue;
bool flag=;
copy(n,r.father,c.father);
for(int k=;(<<k)<=j;++k)
if(j&(<<k)){
int ret=(k+)+last;
if(r.find(d[ret].from)==r.find(d[ret].to)){
flag=;
break;
}
r.unionn(d[ret].from,d[ret].to);
}
if(flag==){
ans[d[last+].val]++;
copy(n,right.father,r.father);
}
}
copy(n,c.father,right.father);
last+=w[d[last+].val];
}
for(int i=;i<=maxval;++i)
if(w[i]){
last=i;
break;
}
for(int i=last;i<=maxval;++i){
if(ans[i]&&i!=last){
ans[i]=(ans[i]*ans[last])%mod;
last=i;
}
}
printf("%d\n",ans[last]);
return ;
}

【Luogu】P4208最小生成树计数(状压乱搞)的更多相关文章

  1. [BZOJ1494][NOI2007]生成树计数 状压dp 并查集

    1494: [NOI2007]生成树计数 Time Limit: 5 Sec  Memory Limit: 64 MBSubmit: 793  Solved: 451[Submit][Status][ ...

  2. luogu 2704 炮兵阵地 状压dp

    状压的基础题吧 第一次看感觉难上天,后来嘛就.. 套路:先根据自身状态筛出可行状态,再根据地图等其他限制条件筛选适合的状态加入答案 f i,j,k 分别代表 行数,本行状态,上行状态,再累加答案即可 ...

  3. HDU5117 Fluorescent 期望 计数 状压dp 动态规划

    原文链接https://www.cnblogs.com/zhouzhendong/p/HDU5117.html 题目传送门 - HDU5117 题意 $T$ 组数据. 给你 $n$ 盏灯 ,$m$ 个 ...

  4. Luogu 3959 [NOIP2017] 宝藏- 状压dp

    题解 真的想不到这题状压的做法...听说还有跑的飞快的模拟退火,要是现场做绝对滚粗QAQ. 不考虑深度,先预处理出 $pt_{i, S}$ 表示让一个不属于 集合 $S$ 的 点$i$ 与点集 $S$ ...

  5. Luogu P1134 阶乘问题 【数学/乱搞】 By cellur925

    输入输出格式 输入格式: 仅一行包含一个正整数 NN . 输出格式: 一个整数,表示最右边的非零位的值. 输入输出样例 输入样例#1: 12 输出样例#1: 6 说明 USACO Training S ...

  6. [CSP-S模拟测试]:统计(树状数组+乱搞)

    题目传送门(内部题120) 输入格式 第一行,两个正整数$n,m$. 第二行,$n$个正整数$a_1,a_2,...,a_n$,保证$1\leqslant a_i\leqslant n$,可能存在相同 ...

  7. BZOJ 1012: [JSOI2008]最大数maxnumber 单调队列/线段树/树状数组/乱搞

    1012: [JSOI2008]最大数maxnumber Time Limit: 3 Sec  Memory Limit: 162 MBSubmit: 4750  Solved: 2145[Submi ...

  8. hdu 5094 状压bfs+深坑

    http://acm.hdu.edu.cn/showproblem.php?pid=5094 给出n*m矩阵 给出k个障碍,两坐标之间存在墙或门,门最多10种,状压可搞 给出s个钥匙位置及编号,相应的 ...

  9. hdu 1429 bfs+状压

    题意:这次魔王汲取了上次的教训,把Ignatius关在一个n*m的地牢里,并在地牢的某些地方安装了带锁的门,钥匙藏在地牢另外的某些地方.刚开始 Ignatius被关在(sx,sy)的位置,离开地牢的门 ...

随机推荐

  1. 使用FontDialog组件设置字体

    实现效果: 知识运用: FontDialog组件的Font属性 //获取或设置选定的字体 public Font Font  { get;set; } 实现代码: private void butto ...

  2. 在DataGridView控件中设置数据显示格式

    实现效果: 知识运用: DataGridViewCellStyle类的Format属性 //获取或设置应用于DataGridView单元格的文本内容的格式字符串 public string Forma ...

  3. Ubuntu编译Android源码过程中的空间不足解决方法

    Android源码一般几十G,就拿Android5.0来说,下载下来大概也有44G左右,和编译产生的文件以及Ubuntu系统占用的空间加起来,源码双倍的空间都不够有.编译源码前能分配足够的空间再好不过 ...

  4. jQuery向界面输出时保留两位小数

    通过JSTL下的<fmt:formatNumber>标签实现,具体实现代码如下: <%@ taglib uri="http://java.sun.com/jsp/jstl/ ...

  5. Spring中使用事务搭建转账环境 转账操作,

    演示不使用事务出现异常情况 Dao层两个方法lessMoney()和moreMoney() package com.swift; import org.springframework.jdbc.cor ...

  6. 【转】VC自定义消息

    MFC一般可利用ClassWizard类向导添加消息和消息处理函数,但用户自定义消息必须手工输入,现将vc自定义消息方法步骤记录如下: (1)定义消息 利用#define语句直接定义用户自己的消息(既 ...

  7. python2和python3中filter函数

    在python2和python3中filter是不同的,其中在python2中filter返回的是一个list,可以直接使用 >>> a = [1,2,3,4,5,6,7] > ...

  8. 15.Yii2.0框架where单表查询

    目录 新建控制器 HomeController.php 新建model article.php 新建控制器 HomeController.php D:\xampp\htdocs\yii\control ...

  9. JAVA基础篇—异常

    五种常见异常 1.NullPointerException 空指针 2.ClassNotFoundException 指定类不存在 3.ArithmeticException运算异常 4.ArrayI ...

  10. npm 安装express npm ERR! code UNABLE_TO_VERIFY_LEAF_SIGNATURE

    npm安装总是报错 报错信息: 解决方案: 在命令行输入: npm config set strict-ssl false 设置之后即可安装软件: