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. 【JDBC核心】数据库事务

    数据库事务 概述 事务是逻辑上的一组操作,或者说一个独立的工作单元.事务内的语句,要么全部执行成功,要么全部执行失败. 事务处理 数据一旦提交,就不可回滚.数据意味着提交的情况: 当一个连接对象被创建 ...

  2. 关于软件架构中的b/s

    **B/S架构 b/s只需要一个浏览器,用户就可以通过不同的网址访问不同的服务器程序. 优点:开发,安装,部署,维护简单 缺点:对硬件要求过高,用户的体验会受到影响 首先是资源分类:**可以分为静态资 ...

  3. Ossec 安装并配置邮件通知

    Ossec 安装并配置邮件通知 目录 Ossec 安装并配置邮件通知 1. 介绍 2. 软硬件环境 3. 安装步骤 3.1 Server 3.2 Agent 3.3 配置邮件通知 4. 参考资料 1. ...

  4. MySQL select 语句指定字段查询

    指定字段查询 SELECT 语法 SELECT [ALL | DISTINCT] {* | table.* | [table.field1[as alias1][,table.field2[as al ...

  5. CTFHub - Web(二)

    目录遍历: 法一: 依次查看目录即可: 法二: 利用脚本:  #!/usr/bin/python3  # -*- coding: utf-8 -*-  # --author:valecalida-- ...

  6. service自动发现,yaml文件管理内外部端口访问

    service服务发现 [root@k8s-master ~]# vim busybox-5d4f595646-dzjv4.yaml apiVersion: v1 kind: Pod metadata ...

  7. 使用.net中的API网关模式封装微服务

    在本文中,我们将了解如何使用API网关模式来封装微服务并抽象出底层实现细节,从而允许使用者拥有进入我们系统的一致入口点. 为了构建和测试我们的应用程序,我们需要: 1.Visual Studio 20 ...

  8. PyTorch 于 JupyterLab 的环境准备

    PyTorch 是目前主流的深度学习框架之一,而 JupyterLab 是基于 Web 的交互式笔记本环境.于 JupyterLab 我们可以边记笔记的同时.边执行 PyTorch 代码,便于自己学习 ...

  9. fsutil比较有用的几个命令

    Fsutil:fsinfo 主要由专业支持者使用.列出所有驱动器,查询驱动器类型,查询卷信息,查询特定的 卷信息或文件系统统计信息. 语法参数 drives 列出计算机中所有的驱动器. drivety ...

  10. Docker 拉取镜像速度太慢

    Docker Hub 是我们分发和获取 Docker 镜像的中心,但由于服务器位于海外,经常会出现拉取/上传镜像时速度太慢或无法访问的情况.再加上运营方不断对 Docker Hub 的免费使用进行限制 ...