题目链接

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

  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. 51nod 1631 小鲨鱼在51nod小学

    基准时间限制:1 秒 空间限制:131072 KB 分值: 20 难度:3级算法题 鲨鱼巨巨2.0(以下简称小鲨鱼)以优异的成绩考入了51nod小学.并依靠算法方面的特长,在班里担任了许多职务.   ...

  2. 洛谷 P1784 数独

    题目描述 数独是根据9×9盘面上的已知数字,推理出所有剩余空格的数字,并满足每一行.每一列.每一个粗线宫内的数字均含1-9,不重复.每一道合格的数独谜题都有且仅有唯一答案,推理方法也以此为基础,任何无 ...

  3. Bot Framework:Activity类简明指南

    Bot Framework相关文档:https://docs.botframework.com/en-us/csharp/builder/sdkreference/attachments.html B ...

  4. Vue中使用computed与watch结合实现数据变化监听

    目的:当数据变化时,为其中重要数据增加边框,实现闪烁以达到提醒目的.数据格式如下,只有在未处理火警/故障时增加闪烁边框.可以使用watch进行深度监听.数据格式已定,也非常明确要监听的数据是有两个.既 ...

  5. JS编程规范指南

    原文:github.com/ryanmcdermott/clean-code-javascript 说明:本文翻译自 github 上的一个项目,只取部分精华. 一.变量 用有意义且常用的单词命名 / ...

  6. c++文件偏移

    #include <iostream> #include <fstream> #include <cassert> using namespace std; int ...

  7. Luogu P2073 送花

    权值线段树的模板题 然而AC后才发现,可以用\(\tt{set}\)水过-- 权值线段树类似于用线段树来实现平衡树的一些操作,代码实现还是比较方便的 #include<iostream> ...

  8. 【dp】P1077 摆花

    基础DP题 题目描述 小明的花店新开张,为了吸引顾客,他想在花店的门口摆上一排花,共m盆.通过调查顾客的喜好,小明列出了顾客最喜欢的n种花,从1到n标号.为了在门口展出更多种花,规定第i种花不能超过a ...

  9. Linux Ptrace 详解

    转 https://blog.csdn.net/u012417380/article/details/60470075 Linux Ptrace 详解 2017年03月05日 18:59:58 阅读数 ...

  10. spring IOC注解与xml配置

    转载自:https://blog.csdn.net/u014292162/article/details/52277756 IOC 1小案例 将对象的依赖交给配置文件来配置(配置文件的名字是可以任意的 ...