好像也没那么难写

LOJ #2547

Luogu P4517


题意

在一棵点仙人掌中等概率选择一个点集

求选出点集的斯坦纳树大小的期望

定义点仙人掌为不存在一个点在多个简单环中的连通图

斯坦纳树为在原图中连通给定点集的一棵生成树

点数不超过$ 200$


$ Solution$

直接计算不太方便

我们转而考虑每条边的贡献

如果这条边不在环上则一定是割边

若这条边两边都有点被选择就会被计算贡献

如果这条边在环上比较复杂

对于一个环,我们选择的边的数量一定是环大小-最长没选中点的路径的长度

定义选中某个点为存在至少一个点满足这个点到环的最近点为这个点

用$ f(L,R,k,0/1)$表示将环展开成链之后选中的左右端点为$ L,R$,这之间的最长空路径长度为$ k$且已经/没有取到最长路径的方案数

转移可以用前缀和优化$ O(n^3)$计算出$ DP$值

然后对于一个$ f(L,R,k,1)$最长空路径长度为$ max(k,n+L-R)$然后统计答案

总复杂度为$ O(n^3)$


$ my \ code$

#include<ctime>
#include<cmath>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<queue>
#define p 1000000007
#define rt register int
#define ll long long
using namespace std;
inline ll read(){
ll x = ; char zf = ; char ch = getchar();
while (ch != '-' && !isdigit(ch)) ch = getchar();
if (ch == '-') zf = -, ch = getchar();
while (isdigit(ch)) x = x * + ch - '', ch = getchar(); return x * zf;
}
void write(ll y){if(y<)putchar('-'),y=-y;if(y>)write(y/);putchar(y%+);}
void writeln(const ll y){write(y);putchar('\n');}
int k,m,n,x,y,z,cnt,ans;
int e[][];
int f[][],qz0[],qz1[],jc[];
void dp(int n,int *A){
if(n<=)return;
for(rt i=;i<=n;i++)
for(rt k=;k<=n;k++){
memset(qz0,,sizeof(qz0));
memset(qz1,,sizeof(qz1));
qz0[i]=A[i];f[i][]=A[i];
for(rt j=i+;j<=n;j++){
(f[j][]=1ll*A[j]*(qz0[j-]-qz0[max(j-k,i-)])%p)%=p,
(f[j][]=1ll*A[j]*(qz1[j-]-qz1[max(j-k,i-)])%p)%=p; if(j-k>=i)(f[j][]+=(1ll*A[j]*(f[j-k][]+f[j-k][])%p)%p)%=p;
int len=max(k,n-j+i);
(cnt+=1ll*f[j][]*(n-len)%p)%=p; qz1[j]=(qz1[j-]+f[j][])%p;
qz0[j]=(qz0[j-]+f[j][])%p;
}
}
}
int a[],dfn[],low[],sta[],s[],sl,top,tot;
bool vis[];
int js(int x){
int sum=;vis[x]=;
for(rt i=;i<=n;i++)if(!vis[i]&&e[x][i])(sum+=js(i))%=p;
return sum;
}
void calc(int n,int *s){
if(!n)return;
memset(vis,,sizeof(vis));
for(rt i=;i<=n;i++)vis[s[i]]=;
for(rt i=;i<=n;i++)a[i]=jc[js(s[i])]-;
dp(n,a);
}
void dfs(int x,int pre){
dfn[x]=low[x]=++tot;sta[++top]=x;
for(rt i=;i<=n;i++)if(e[x][i]&&x!=i&&pre!=i){
if(!dfn[i]){
dfs(i,x);
low[x]=min(low[x],low[i]);
if(low[i]>dfn[x]){
sl=;while(sta[top+]!=i)s[++sl]=sta[top--];
calc(sl,s);memset(vis,,sizeof(vis));
vis[x]=;int gs=js(i);
(cnt+=1ll*(jc[gs]-)*(jc[n-gs]-)%p)%=p;
}
}
else if(i!=pre)low[x]=min(low[x],dfn[i]);
}
if(x==){
sl=;while(top)s[++sl]=sta[top--];
calc(sl,s);
}
}
int inv(int x){return (x==)?:1ll*inv(p%x)*(p-p/x)%p;}
int main(){
n=read();m=read();
jc[]=;
for(rt i=;i<=n;i++)jc[i]=1ll*jc[i-]*%p;
for(rt i=;i<=m;i++){
x=read();y=read();
e[x][y]=e[y][x]=;
}
dfs(,);
cout<<(1ll*cnt*inv(jc[n])%p+p)%p;
return ;
}

LOJ #2547 Luogu P4517「JSOI2018」防御网络的更多相关文章

  1. LOJ 2547 「JSOI2018」防御网络——思路+环DP

    题目:https://loj.ac/problem/2547 一条树边 cr->v 会被计算 ( n-siz[v] ) * siz[v] 次.一条环边会被计算几次呢?于是去写了斯坦纳树. #in ...

  2. 【LOJ】 #2547. 「JSOI2018」防御网络

    题解 如果只是一棵树的话,那么就枚举每条边,分成两部分大小为\(a\)和\(b\) 那么这条边被统计的方案数是\((2^a - 1)(2^b - 1)\) 如果是一个环的话,我们枚举环上至少有\(N ...

  3. LOJ #2116 Luogu P3241「HNOI2015」开店

    好久没写数据结构了 来补一发 果然写的时候思路极其混乱.... LOJ #2116 Luogu P3241 题意 $ Q$次询问,求树上点的颜色在$ [L,R]$中的所有点到询问点的距离 强制在线 询 ...

  4. LOJ#2249 Luogu P2305「NOI2014」购票

    几乎肝了半个下午和整个晚上 斜率优化的模型好多啊... LOJ #2249 Luogu P2305 题意 给定一棵树,第$ i$个点如果离某个祖先$ x$的距离不超过$ L_i$,可以花费$ P_i· ...

  5. LOJ #2527 Luogu P4491「HAOI2018」染色

    好像网上没人....和我推出....同一个式子啊..... LOJ #2527 Luogu P4491 题意 $ n$个格子中每个格子可以涂$ m$种颜色中的一种 若有$ k$种颜色恰好涂了$ s$格 ...

  6. 「JSOI2018」战争

    「JSOI2018」战争 解题思路 我们需要每次求给一个凸包加上一个向量后是否与另外一个凸包相交,也就是说是否存在 \[ b\in B,(b+w)\in A \] 这里 \(A, B\) 表示凸包内部 ...

  7. 「JSOI2014」电信网络

    「JSOI2014」电信网络 传送门 一个点选了就必须选若干个点,最大化点权之和,显然最大权闭合子图问题. 一个点向它范围内所有点连边,直接跑最大权闭合子图即可. 参考代码: #include < ...

  8. LOJ 2550 「JSOI2018」机器人——找规律+DP

    题目:https://loj.ac/problem/2550 只会写20分的搜索…… #include<cstdio> #include<cstring> #include&l ...

  9. LOJ 2548 「JSOI2018」绝地反击 ——二分图匹配+网络流手动退流

    题目:https://loj.ac/problem/2548 如果知道正多边形的顶点,就是二分答案.二分图匹配.于是写了个暴力枚举多边形顶点的,还很愚蠢地把第一个顶点枚举到 2*pi ,其实只要 \( ...

随机推荐

  1. 跟我一起用node-express搭建一个小项目[一]

    我一直以为你要学nodejs你就要掌握很多东西啊!比如js最少得看10本书吧,nodejs书籍得看吧!其实呢,到最后,你会发现,因为工作,或者找工作的需要,什么不学,那些js不懂 也没有很大的关系.所 ...

  2. 第二节,神经网络中反向传播四个基本公式证明——BackPropagation

    假设一个三层的神经网络结构图如下: 对于一个单独的训练样本x其二次代价函数可以写成: C = 1/2|| y - aL||2 = 1/2∑j(yj - ajL)2 ajL=σ(zjL) zjl = ∑ ...

  3. java键盘中输入q退出

    用 java.util.Scanner 如下 public static void main(String[] args) { while(true){ Scanner scan = new Scan ...

  4. 高级组件——菜单栏JMenuBar

    菜单栏JMenuBar,菜单JMenu,菜单项JMenuItem 一旦A有子菜单项,则A为菜单JMenu,而不是菜单项JMenuItem import javax.swing.*; import ja ...

  5. storm集群配置

    环境:centos6.4软件:jzmq-master-----java与c++通讯的桥梁,有了它,就可以使用zeromp了storm-0.8.2zeromq-2.1.7-----号称史上最牛逼的消息队 ...

  6. flask form表单验证

    新建forms.py文件 #!/usr/bin/env python #-*-coding:utf--*- #导入模块 from flask_wtf import FlaskForm #FlaskFo ...

  7. Ansible Callback

    非api模式下自定义callback ansible.cfg中开启callback功能 callback_plugins = /usr/share/ansible/plugins/callback # ...

  8. js中Date与timestamp(时间戳)的相互转换

    #时间(Date)转时间戳(Timestamp): 1.var timestamp1 = (new Date()).valueOf(); // 结果:1535374762785,通过valueOf() ...

  9. Java中的XML

    XML是一种可扩展的标记语言,可扩展就是<>内的东西可以自己定义,可以随便写.标记语言就是加了<>符号的 .HTML是超文本标记语言,不可以拓展,因为你写个<p> ...

  10. oracle中查看所有表和字段以及表注释字段注释

    获取表:select table_name from user_tables; //当前用户拥有的表 select table_name from all_tables; //所有用户的表 selec ...