HDU5739 Fantasia

题意:

给出一张\(N\)个点的无向图\(G\),每个点都有权值\(w_i\),要求计算\(\sum_{i=1}^{N}i\cdot G_i % 1e9+7\)

其中\(G_i\)为删掉点\(i\)之后剩下各连通块内点权乘积之和

题解:

显然对于不是割点的点很容易计算出答案

对于割点,我们需要知道删掉这个点之后产生的新的连通块的点权乘积和

\(tarjan\)过程中可以直接处理出各联通子图的点权乘积(除了父节点所在的子图)

而父节点所在子图的点权乘积可以用整张图的点权乘积去除掉除它以外的点的点权乘积

具体实现看代码

view code
//#pragma GCC optimize("O3")
//#pragma comment(linker, "/STACK:1024000000,1024000000")
#include<bits/stdc++.h>
using namespace std;
function<void(void)> ____ = [](){ios_base::sync_with_stdio(false); cin.tie(0); cout.tie(0);};
typedef long long int LL;
const int MAXN = 2e5+7;
const LL MOD = 1e9+7;
int n,m,bccid[MAXN],dfn[MAXN],low[MAXN],ID,w[MAXN],bel[MAXN],idx;
vector<int> G[MAXN],pt[MAXN];
LL tot,ans,f[MAXN],gw[MAXN],mul[MAXN],subsum[MAXN],submul[MAXN];
bool iscut[MAXN];
LL ksm(LL a, LL b){
LL ret = 1;
while(b){
if(b&1) ret = ret * a % MOD;
b >>= 1;
a = a * a % MOD;
}
return ret;
}
LL inv(LL x){ return ksm(x,MOD-2); }
void init(){
for(int i = 1; i <= n; i++) G[i].clear();
memset(dfn+1,0,n<<2);
memset(bel+1,0,n<<2);
memset(iscut+1,0,n);
fill(submul+1,submul+1+n,1);
fill(subsum+1,subsum+1+n,0);
ans = tot = ID = idx = 0;
}
void tarjan(int u, int par, int id){
pt[id].push_back(u);
bel[u] = id;
dfn[u] = low[u] = ++idx;
mul[id] = mul[id] * w[u] % MOD;
int child = 0;
for(int v : G[u]){
if(v==par) continue;
if(!dfn[v]){
child++;
LL tmp = mul[ID];
tarjan(v,u,id);
low[u] = min(low[u],low[v]);
if(low[v]>=dfn[u]){
if(par) iscut[u] = true;
LL sub = mul[ID] * inv(tmp) % MOD;
// 由于不确定根节点是否是割点,所以先当作割点来处理
subsum[u] = (subsum[u] + sub) % MOD;
submul[u] = submul[u] * sub % MOD;
}
}
else low[u] = min(low[u],dfn[v]);
}
if(!par and child > 1) iscut[u] = true;
}
void solve(){
scanf("%d %d",&n,&m);
init();
for(int i = 1; i <= n; i++) scanf("%d",&w[i]);
for(int i = 1; i <= m; i++){
int u, v; scanf("%d %d",&u,&v);
G[u].push_back(v); G[v].push_back(u);
}
for(int i = 1; i <= n; i++) if(!dfn[i]){
pt[++ID].clear();
mul[ID] = 1;
tarjan(i,0,ID);
tot = (tot + mul[ID]) % MOD;
for(int x : pt[ID]){
if(x==i) continue;
subsum[x] = (subsum[x] + mul[ID] * inv(submul[x]*w[x]%MOD) % MOD) % MOD;
}
}
for(int i = 1; i <= n; i++){
LL res = 0;
if(iscut[i]) res = (tot - mul[bel[i]] + subsum[i] + MOD) % MOD;
else{
if(pt[bel[i]].size() == 1) res = (tot - w[i] + MOD) % MOD;
else res = (tot - mul[bel[i]] + mul[bel[i]] * inv(w[i]) % MOD + MOD) % MOD;
}
ans = (ans + i * res) % MOD;
}
printf("%I64d\n",ans);
}
int main(){
int tt;
for(scanf("%d",&tt); tt; tt--) solve();
return 0;
}

HDU5739 Fantasia【点双连通分量 割点】的更多相关文章

  1. poj 1523 SPF(双连通分量割点模板)

    题目链接:http://poj.org/problem?id=1523 题意:给出无向图的若干条边,求割点以及各个删掉其中一个割点后将图分为几块. 题目分析:割点用tarjan算法求出来,对于每个割点 ...

  2. HDU 3686 Traffic Real Time Query System(双连通分量缩点+LCA)(2010 Asia Hangzhou Regional Contest)

    Problem Description City C is really a nightmare of all drivers for its traffic jams. To solve the t ...

  3. Tarjan应用:求割点/桥/缩点/强连通分量/双连通分量/LCA(最近公共祖先)【转】【修改】

    一.基本概念: 1.割点:若删掉某点后,原连通图分裂为多个子图,则称该点为割点. 2.割点集合:在一个无向连通图中,如果有一个顶点集合,删除这个顶点集合,以及这个集合中所有顶点相关联的边以后,原图变成 ...

  4. (转)Tarjan应用:求割点/桥/缩点/强连通分量/双连通分量/LCA(最近公共祖先)

    基本概念: 1.割点:若删掉某点后,原连通图分裂为多个子图,则称该点为割点. 2.割点集合:在一个无向连通图中,如果有一个顶点集合,删除这个顶点集合,以及这个集合中所有顶点相关联的边以后,原图变成多个 ...

  5. Tarjan算法应用 (割点/桥/缩点/强连通分量/双连通分量/LCA(最近公共祖先)问题)(转载)

    Tarjan算法应用 (割点/桥/缩点/强连通分量/双连通分量/LCA(最近公共祖先)问题)(转载) 转载自:http://hi.baidu.com/lydrainbowcat/blog/item/2 ...

  6. Tarjan算法求解无向连通图的割点、割边、点双连通分量和边双连通分量的模板

    历时好几天,终于完工了! 支持无向图四种功能:1.割点的求解 2.割边的求解 3.点双连通分量的求解 4.边双连通分量的求解 全部支持重边!!!!全部支持重边!!!!全部支持重边!!!! 测试数据: ...

  7. CF487 E. Tourists [点双连通分量 树链剖分 割点]

    E. Tourists 题意: 无向连通图 C a w: 表示 a 城市的纪念品售价变成 w. A a b: 表示有一个游客要从 a 城市到 b 城市,你要回答在所有他的旅行路径中最低售价的最低可能值 ...

  8. 图论-桥/割点/双连通分量/缩点/LCA

    基本概念: 1.割点:若删掉某点后,原连通图分裂为多个子图,则称该点为割点. 2.割点集合:在一个无向连通图中,如果有一个顶点集合,删除这个顶点集合,以及这个集合中所有顶点相关联的边以后,原图变成多个 ...

  9. Tarjan算法初探(3):求割点与桥以及双连通分量

    接上一节Tarjan算法初探(2):缩点 在此首先提出几个概念: 割点集合:一个无向连通图G 若删除它的一个点集 以及点集中所有点相连的边(任意一端在点集中)后 G中有点之间不再连通则称这个点集是它的 ...

随机推荐

  1. MyBatis初级实战之一:Spring Boot集成

    欢迎访问我的GitHub https://github.com/zq2599/blog_demos 内容:所有原创文章分类汇总及配套源码,涉及Java.Docker.Kubernetes.DevOPS ...

  2. 关于spring-data与elasticsearch的使用,自定义repository

    之前没有使用过spring-data,关于spring-data有很多很棒的设计,例如仅仅只需要声明一个接口就行,你甚至都不需要去实现,spring-data有内置默认的实现类,基本就上完成绝大多数对 ...

  3. 【Linux】查看系统僵尸进程

    ps -ef|grep -v grep|grep defunct 如果这个有显示内容的话,可以手动将进程kill掉即可 ---------------------------------------- ...

  4. 【ORACLE】11g rac+dg

    首先感谢群友分享的文档,在这里先感谢哆啦B梦,非常感谢 该文档主要指导如何利用现有的RAC环境搭建一套RAC与单实例的DG的环境  ============================主机配置信息 ...

  5. bootstrap弹出层嵌套弹出层后文本框不能获得焦点输入

    如图上 我从页面打开一个bootstrap弹出层 然后又在 bootstrap弹出层的基础上打开一个layui的弹出层  打开后发现文本域获取不到焦点不能输入内容 而该弹出层显示的层级体现出来了 按钮 ...

  6. PAT Advanced 1004 Counting Leaves

    题目与翻译 1004 Counting Leaves 数树叶 (30分) A family hierarchy is usually presented by a pedigree tree. You ...

  7. 面试常问的ArrayQueue底层实现

    public class ArrayQueue<T> extends AbstractList<T>{ //定义必要的属性,容量.数组.头指针.尾指针 private int ...

  8. torch.optim.SGD()各参数的解释

    看pytorch中文文档摘抄的笔记. class torch.optim.SGD(params, lr=, momentum=0, dampening=0, weight_decay=0, neste ...

  9. CentOS对接GlusterFS

    存储节点部署示例环境,仅供参考 主机名 IP 系统 gfs01 10.10.10.13 CentOS 7.4.1708 gfs02 10.10.10.14 CentOS 7.4.1708 一.Glus ...

  10. Kubernetes调整Node节点快速驱逐pod的时间

    在高可用的k8s集群中,当Node节点挂掉,kubelet无法提供工作的时候,pod将会自动调度到其他的节点上去,而调度到节点上的时间需要我们慎重考量,因为它决定了生产的稳定性.可靠性,更快的迁移可以 ...