洛谷P4517 [JSOI2018]防御网络(dp)
题面
题解
翻译一下题意就是每次选出一些点,要用最少的边把这些点连起来,求期望边数
我也不知道为什么反正总之就是暴力枚举太麻烦了所以我们考虑贡献
如果一条边是割边,那么它会在图里当且仅当两边的联通块中都有点被选,设其中一边的点的个数为\(siz\),那么方案数就是\((2^{siz}-1)(2^{n-siz}-1)\)
然而如果一条边是环边就会变得非常麻烦了……每种方案相当于这个环上有若干个点被标记,要用最少的边数将它们连起来,那么边数就是环的大小减去\(\max(\)两个相邻点之间的边数\()\)
这个不能分开考虑了,我们把整个环给一起考虑
设\(dp_{i,j,k}\)表示选择的点中左端点为\(i\),右端点为\(j\),不考虑\(j->n->i\)这条路径的情况下的两两相邻点之间最大值为\(k\)的情况,设环长为\(n\),那么这个就会产生\((n-\max(k,n+i-j))\times dp_{i,j,k}\)的贡献
转移方程为
\]
上面的方程的意思就是,如果\(j\)和前面一个点的长度恰好为\(k\),那么前面最大长度可以任取,否则前面最大长度就必须等于\(k\)
发现转移方程里的两个柿子都可以写成前缀和的形式,那么我们一边计算一边维护前缀和,总的复杂度就是\(O(n^3)\)
//minamoto
#include<bits/stdc++.h>
#define R register
#define fp(i,a,b) for(R int i=(a),I=(b)+1;i<I;++i)
#define fd(i,a,b) for(R int i=(a),I=(b)-1;i>I;--i)
#define go(u) for(int i=head[u],v=e[i].v;i;i=e[i].nx,v=e[i].v)
template<class T>inline bool cmin(T&a,const T&b){return a>b?a=b,1:0;}
using namespace std;
char buf[1<<21],*p1=buf,*p2=buf;
inline char getc(){return p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++;}
int read(){
R int res,f=1;R char ch;
while((ch=getc())>'9'||ch<'0')(ch=='-')&&(f=-1);
for(res=ch-'0';(ch=getc())>='0'&&ch<='9';res=res*10+ch-'0');
return res*f;
}
const int N=1005,P=1e9+7;
inline int add(R int x,R int y){return x+y>=P?x+y-P:x+y;}
inline int dec(R int x,R int y){return x-y<0?x-y+P:x-y;}
inline int mul(R int x,R int y){return 1ll*x*y-1ll*x*y/P*P;}
int ksm(R int x,R int y){
R int res=1;
for(;y;y>>=1,x=mul(x,x))if(y&1)res=mul(res,x);
return res;
}
struct eg{int v,nx,w,f;}e[N<<1];int head[N],tot=1;
inline void add_edge(R int u,R int v){e[++tot]={v,head[u]},head[u]=tot;}
int dfn[N],low[N],sz[N],vis[N],sum1[N][N],sum2[N][N],st[N],val[N];
int n,m,tim,res,top,tmp,u,v;
void tarjan(int u,int fa){
low[u]=dfn[u]=++tim,sz[u]=1;
go(u)if(v!=fa){
if(!dfn[v])tarjan(v,u),cmin(low[u],low[v]),sz[u]+=sz[v];
else cmin(low[u],dfn[v]);
if(low[v]>dfn[u]){
e[i].f=e[i^1].f=1,res=add(res,mul(ksm(2,sz[v])-1,ksm(2,n-sz[v])-1));
e[i].w=sz[v],e[i^1].w=n-sz[v];
}
}
}
inline int nxt(R int u){go(u)if(!e[i].f&&!vis[v])return v;return 0;}
void solve(int p){
top=0;while(p)st[++top]=p,vis[p]=1,p=nxt(p);
if(top==1)return;
fp(i,1,top)val[i]=1;
fp(u,1,top)go(st[u])val[u]+=e[i].w;
fp(i,1,top)val[i]=ksm(2,val[i])-1;
fp(i,1,top-1){
fp(j,0,top)sum2[i][j]=val[i];
fp(j,i+1,top)fp(k,1,top){
tmp=0;
if(j-i>=k){
tmp=mul(val[j],add(sum2[j-k][k],dec(sum1[j-1][k],sum1[j-k][k])));
res=add(res,mul(tmp,top-max(top+i-j,k)));
}
sum1[j][k]=add(sum1[j-1][k],tmp),sum2[j][k]=add(sum2[j][k-1],tmp);
}
fp(j,i,top)fp(k,0,top)sum1[j][k]=sum2[j][k]=0;
}
}
int main(){
// freopen("testdata.in","r",stdin);
n=read(),m=read();
fp(i,1,m)u=read(),v=read(),add_edge(u,v),add_edge(v,u);
tarjan(1,0);
fp(i,1,n)if(!vis[i])solve(i);
printf("%d\n",mul(res,ksm(ksm(2,n),P-2)));
return 0;
}
洛谷P4517 [JSOI2018]防御网络(dp)的更多相关文章
- 【BZOJ5315】[JSOI2018]防御网络(动态规划,仙人掌)
[BZOJ5315][JSOI2018]防御网络(动态规划,仙人掌) 题面 BZOJ 洛谷 题解 显然图是仙人掌. 题目给了斯坦纳树就肯定不是斯坦纳树了,,,, 总不可能真让你\(2^n\)枚举点集再 ...
- 洛谷P1783 海滩防御 分析+题解代码
洛谷P1783 海滩防御 分析+题解代码 题目描述: WLP同学最近迷上了一款网络联机对战游戏(终于知道为毛JOHNKRAM每天刷洛谷效率那么低了),但是他却为了这个游戏很苦恼,因为他在海边的造船厂和 ...
- 缩点【洛谷P1262】 间谍网络
[洛谷P1262] 间谍网络 题目描述 由于外国间谍的大量渗入,国家安全正处于高度的危机之中.如果A间谍手中掌握着关于B间谍的犯罪证据,则称A可以揭发B.有些间谍收受贿赂,只要给他们一定数量的美元,他 ...
- 洛谷 P5279 - [ZJOI2019]麻将(dp 套 dp)
洛谷题面传送门 一道 dp 套 dp 的 immortal tea 首先考虑如何判断一套牌是否已经胡牌了,考虑 \(dp\).我们考虑将所有牌按权值大小从大到小排成一列,那我们设 \(dp_ ...
- bzoj5315/luoguP4517 [JSOI2018]防御网络(仙人掌,dp)
bzoj5315/luoguP4517 防御网络(仙人掌,dp) bzoj Luogu 题目描述略(太长了) 题解时间 本题和斯坦纳树无关. 题面保证了是一个仙人掌...? 但这个环之间甚至交点都没有 ...
- 洛谷 P1783 海滩防御 解题报告
P1783 海滩防御 题目描述 WLP同学最近迷上了一款网络联机对战游戏(终于知道为毛JOHNKRAM每天刷洛谷效率那么低了),但是他却为了这个游戏很苦恼,因为他在海边的造船厂和仓库总是被敌方派人偷袭 ...
- 洛谷2344 奶牛抗议(DP+BIT+离散化)
洛谷2344 奶牛抗议 本题地址:http://www.luogu.org/problem/show?pid=2344 题目背景 Generic Cow Protests, 2011 Feb 题目描述 ...
- Lightning Conductor 洛谷P3515 决策单调性优化DP
遇见的第一道决策单调性优化DP,虽然看了题解,但是新技能√,很开森. 先%FlashHu大佬,反正我是看了他的题解和精美的配图才明白的,%%%巨佬. 废话不多说,看题: 题目大意 已知一个长度为n的序 ...
- 洛谷P1541 乌龟棋(四维DP)
To 洛谷.1541 乌龟棋 题目背景 小明过生日的时候,爸爸送给他一副乌龟棋当作礼物. 题目描述 乌龟棋的棋盘是一行N个格子,每个格子上一个分数(非负整数).棋盘第1格是唯一的起点,第N格是终点,游 ...
随机推荐
- Android 4学习(9):用户界面 - THE ANDROID WIDGET TOOLBOX
Android内置了很多View,包括: TextView EditText Chronometer ListView Spinner Button ToggleButton ImageButton ...
- 斯坦福CS229机器学习课程笔记 part2:分类和逻辑回归 Classificatiion and logistic regression
Logistic Regression 逻辑回归 1.模型 逻辑回归解决的是分类问题,并且是二元分类问题(binary classification),y只有0,1两个取值.对于分类问题使用线性回归不 ...
- iOS坑爹的could not find any information for class named xxx
关掉项目也无法解决,最后把文件delete掉,然后选“Remove Reference”,这样就不会真正删除文件.接着选“File -> Add Files to ...”添加回来就可以了.
- 201671010127 2016—2017-2 通过一个小程序对Java的再认识。
学习了将近四周的Java语言,对于Java语言,我也有了更进一步的理解,出于对Java语言的喜爱,我总是喜欢没事的时候,自己敲一些很简单的代码,一边学习Java语言,一边对比C语言,往往可以帮助我们更 ...
- Java中long和Long的区别
Java的数据类型分两种: 1.基本类型:long,int,byte,float,double,char,short,boolean 2. 对象类型(类): Long,Integer,Byte,Flo ...
- resin的几个常用配置
参考原文:http://blog.csdn.net/johnson1492/article/details/7913827 本文着重介绍resin的几个常用配置 注: 1. 本文并非resin.con ...
- codeforce468DIV2——E. Game with String
题目 Vasya and Kolya play a game with a string, using the following rules. Initially, Kolya creates a ...
- web Servise(服务)
服务层:对项目的业务层(业务层调用数据层)的一个包装成对外的服务,是的UI展示可以从单一的WEB扩展为移动端可WINDFROM端等,这叫做面向服务的编程思想. 发布:和网站发布也是一样的. //web ...
- https://github.com/ildoonet/tf-pose-estimation
https://github.com/ildoonet/tf-pose-estimation
- Python编写两个数的加减法游戏
目标: 1.实现两个数的加减法 2.回答者3次输错计算结果后,输出正确结果,并询问回答者是否继续 1.使用常规函数实现两个数的加减法游戏 代码如下: #!/usr/bin/env python # - ...