这个题当时打多校的时候有思路,但是代码能力差,没有写出来

事后看zimpha巨巨的题解,看了觉得基本差不多

核心思路:就是找出割点,然后变成森林,然后树形dp就可以搞了

关键就在重新构图上,缩完点以后,一个割点至少在两个点双里面,这个时候

把割点拿出来,分别和点双连边,也就是说,缩完的点双是不包含割点的,这个可以人为搞一下

(像有的点双里面只包含一个桥边,如果把割点拿出来,点双里面没有点了,这个时候把点双的权值积设为1就好)

然后说是树形dp,其实就是逆元搞一搞,这个很简单,树形dp只处理割点的答案

注意:这个图不联通,这是一个点,还有孤立点,我一直wa在孤立点上,(我的点双模板只能解决至少包含两个点的连通图,这个题丰满了我的模板,感谢)

#include <stdio.h>
#include <iostream>
#include <algorithm>
#include <string.h>
#include <vector>
#include <math.h>
#include <stack>
#include <map>
using namespace std;
typedef long long LL;
const int N = 1e5+;
const LL mod = 1e9+;
LL qpow(LL a,LL b){
LL ret=;
while(b){
if(b&)ret=(ret*a)%mod;
b>>=;
a=(a*a)%mod;
}
return ret;
}
int head[N<<],tot,T,n,m;
struct Edge{
int u,v,next;
}edge[N*];
void addedge(int u,int v){
edge[tot].u=u;
edge[tot].v=v;
edge[tot].next=head[u];
head[u]=tot++;
}
int low[N],dfn[N],clk,cnt,belbcc[N];
bool iscut[N];
vector<int>bcc[N],cut;
stack<int>s;
void init(){
memset(dfn,,sizeof(dfn));
memset(head,-,sizeof(head));
memset(belbcc,,sizeof(belbcc));
tot=clk=cnt=;
cut.clear();
}
LL w[N],bccw[N<<],ret[N],blkw[N<<],zong;
bool vis[N<<];
int blk,bel[N<<];
void dfs(int u,int f){
dfn[u]=low[u]=++clk;
int child=;
if(head[u]==-){
++cnt;bcc[cnt].clear();
bcc[cnt].push_back(u);
belbcc[u]=cnt;
return ;
}
for(int i=head[u];~i;i=edge[i].next){
int to=edge[i].v;
if(!dfn[to]){
++child;s.push(i);dfs(to,u);
low[u]=min(low[u],low[to]);
if(low[to]>=dfn[u]){
iscut[u]=true;++cnt;int x;bcc[cnt].clear();
do{
x=s.top();s.pop(); if(belbcc[edge[x].u]!=cnt){
bcc[cnt].push_back(edge[x].u);
belbcc[edge[x].u]=cnt;
} if(belbcc[edge[x].v]!=cnt){
bcc[cnt].push_back(edge[x].v);
belbcc[edge[x].v]=cnt;
}
}while(x!=i);
}
}
else if(dfn[to]<dfn[u]&&to!=f){
s.push(i);
low[u]=min(low[u],dfn[to]);
}
}
if(!f&&child==)iscut[u]=false;
if(iscut[u])cut.push_back(n+u),bccw[n+u]=w[u];
}
void predfs(int u,int f){
bel[u]=blk;blkw[blk]=blkw[blk]*bccw[u]%mod;
vis[u]=true;
for(int i=head[u];~i;i=edge[i].next){
int v=edge[i].v;
if(v==f)continue;
predfs(v,u);
}
}
LL treedp(int u,int f){
LL pro=,sum=,tmp;
vis[u]=false;
for(int i=head[u];~i;i=edge[i].next){
int v=edge[i].v;
if(v==f)continue;
tmp=treedp(v,u);
pro=pro*tmp%mod;
sum=(sum+tmp)%mod;
}
pro=pro*bccw[u]%mod;
if(u>n){
tmp=blkw[bel[u]];
tmp=tmp*qpow(pro,mod-)%mod;
sum=(sum+tmp)%mod;
tmp=zong-blkw[bel[u]];
while(tmp<)tmp+=mod;
ret[u-n]=(sum+tmp)%mod;
}
return pro;
}
int main(){
scanf("%d",&T);
while(T--){
scanf("%d%d",&n,&m);
for(int i=;i<=n;++i)scanf("%I64d",&w[i]);
init();
for(int i=;i<m;++i){
int u,v;scanf("%d%d",&u,&v);
addedge(u,v);addedge(v,u);
}
for(int i=;i<=n;++i)if(!dfn[i])dfs(i,);
tot=;memset(head,-,sizeof(head));
for(int i=;i<=cnt;++i){
bccw[i]=;
for(int j=;j<bcc[i].size();++j){
int u=bcc[i][j];
if(iscut[u]) addedge(i,u+n),addedge(u+n,i);
else bccw[i]=bccw[i]*w[u]%mod;
}
}
blk=;
for(int i=;i<=cnt;++i)
if(!vis[i]){++blk;blkw[blk]=;predfs(i,);}
for(int i=;i<cut.size();++i)
if(!vis[cut[i]]){++blk;blkw[blk]=;predfs(cut[i],);}
zong=;
for(int i=;i<=blk;++i)zong=(zong+blkw[i])%mod;
for(int i=;i<=cnt;++i)
if(vis[i])treedp(i,);
for(int i=;i<cut.size();++i)
if(vis[cut[i]])treedp(cut[i],);
LL ans=;
for(int i=;i<=n;++i){
if(iscut[i]){
ans=(ans+1ll*i*ret[i]%mod)%mod;
iscut[i]=false;
}
else{
int k=belbcc[i];
k=bel[k];
LL ad=;
if(w[i]!=blkw[k])ad=blkw[k]*qpow(w[i],mod-)%mod;
LL tmp=zong-blkw[k];
while(tmp<)tmp+=mod;
tmp=(tmp+ad)%mod;
ans=(ans+1ll*i*tmp%mod)%mod;
}
}
printf("%I64d\n",ans);
}
return ;
}

HDU5739 Fantasia 树形dp + 点双缩点的更多相关文章

  1. hdu 4612 Warm up 双连通+树形dp思想

    Warm up Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65535/65535 K (Java/Others) Total S ...

  2. HDU4612(Warm up)2013多校2-图的边双连通问题(Tarjan算法+树形DP)

    /** 题目大意: 给你一个无向连通图,问加上一条边后得到的图的最少的割边数; 算法思想: 图的边双连通Tarjan算法+树形DP; 即通过Tarjan算法对边双连通缩图,构成一棵树,然后用树形DP求 ...

  3. HDU 2242 考研路茫茫—空调教室 (边双连通+树形DP)

    <题目链接> 题目大意: 给定一个连通图,每个点有点权,现在需要删除一条边,使得整张图分成两个连通块,问你删除这条边后,两联通块点权值和差值最小是多少. 解题分析: 删除一条边,使原连通图 ...

  4. hdu 2242双联通分量+树形dp

    /*先求出双联通缩点,然后进行树形dp*/ #include<stdio.h> #include<string.h> #include<math.h> #defin ...

  5. HDU5739 Fantasia(点双连通分量 + Block Forest Data Structure)

    题目 Source http://acm.hdu.edu.cn/showproblem.php?pid=5739 Description Professor Zhang has an undirect ...

  6. 洛谷 P2515 [HAOI2010]软件安装(缩点+树形dp)

    题面 luogu 题解 缩点+树形dp 依赖关系可以看作有向边 因为有环,先缩点 缩点后,有可能图不联通. 我们可以新建一个结点连接每个联通块. 然后就是树形dp了 Code #include< ...

  7. 【BZOJ2427】[HAOI2010] 软件安装(缩点+树形DP)

    点此看题面 大致题意: 有\(N\)个软件,每个软件有至多一个依赖以及一个所占空间大小\(W_i\),只有当一个软件的直接依赖和所有的间接依赖都安装了,它才能正常工作并造成\(V_i\)的价值.求在容 ...

  8. 洛谷P2515 [HAOI2010]软件安装(tarjan缩点+树形dp)

    传送门 我们可以把每一个$d$看做它的父亲,这样这个东西就构成了一个树形结构 问题是他有可能形成环,所以我们还需要一遍tarjan缩点 缩完点后从0向所有入度为零的点连边 然后再跑一下树形dp就行了 ...

  9. HDU 2242 连通分量缩点+树形dp

    题目大意是: 所有点在一个连通图上,希望去掉一条边得到两个连通图,且两个图上所有点的权值的差最小,如果没有割边,则输出impossible 这道题需要先利用tarjan算法将在同一连通分量中的点缩成一 ...

随机推荐

  1. REST_FRAMEWORK加深记忆-加了用户登陆认证,自定义权限的API接口

    哈哈,终于快结束了.. urls.py from django.conf.urls import include, url from django.contrib import admin urlpa ...

  2. 解决 Ubuntu 开机 Waiting for 60 seconds more for network configuration

    sudo vim /etc/network/interfaces, 将该文件的内容修改为如下:(也就是说删掉其他的什么auto eth0.auto wlan0) auto lo iface lo in ...

  3. lintcode:哈希函数

    题目: 哈希函数 在数据结构中,哈希函数是用来将一个字符串(或任何其他类型)转化为小于哈希表大小且大于等于零的整数.一个好的哈希函数可以尽可能少地产生冲突.一种广泛使用的哈希函数算法是使用数值33,假 ...

  4. Unix环境编程之定时、信号与中断

    在linux下实现精度较高的定时功能,需要用到setitimer 和 getitimer函数. 函数原型: #include <sys/time.h> int getitimer(int ...

  5. HTML5入门7---"session的会话缓存"和"localStorage的cookie"缓存数据

    <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title> ...

  6. Hibernate逍遥游记-第13章 映射实体关联关系-001用外键映射一对一(<many-to-one unique="true">、<one-to-one>)

    1. <?xml version="1.0"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hi ...

  7. Java多线程3:Thread中start()和run()的区别

    原文:http://www.cnblogs.com/skywang12345/p/3479083.html start() 和 run()的区别说明start():它的作用是启动一个新线程,新线程会执 ...

  8. epoll和poll效率差异

    http://blog.163.com/sky20081816@126/blog/static/164761023201073033517435/ 百度“epoll和poll”

  9. python3.4安装suds

    使用suds访问webservice十分方便 python3.x安装suds会报错“No module named client” 在stackoverflow上找到了替代方法,安装suds-jurk ...

  10. linq to Entity 数据库除了有主键还有唯一索引,是不是不能更新

    数据库建了一个唯一索引,使用linq to ef更新的时候,老是报,索引建冲突,,坑了我一上午,最后把索引删了