以前从来没写过求点双连通分量,现在写一下……

这题还用到了一个叫做block forest data structure,第一次见过……

——对于每一个点双联通分量S, 新建一个节点s, 向S中每个节点v连边. 这样一来, 新增的点和原来图中的点会构成一个森林

主要是这个性质很厉害:

【对于这个森林F, 删掉一个关键点或者一个叶子ii之后, 会得到一个新森林Fi, 这个Fi​​对应的连通块集合和Gi对应的连通块集合其实是一样的(不考虑那些新增的点)】

更具体的题解见http://www.cnblogs.com/WABoss/p/5696926.html

顺便学了一个扩大栈空间的方法:在编译器中加入命令--stack=16777216 (16777216相当于16MB空间)

 #include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
#include<stack>
typedef long long ll;
using namespace std;
const int mo=;
struct edge{int x,y;};
vector<int> g[];
stack<edge> st;
int dfn[],low[],f[],w[],s[],a[],root[],be[],fa[];
bool cut[];
int cas,n,m,t,h,x,y,sum; ll quick(ll x)
{
int y=mo-; ll s=;
while (y)
{
if (y&) s=s*x%mo;
x=x*x%mo;
y>>=;
}
return s;
} void dfs(int x)
{
dfn[x]=low[x]=++h;
int chi=;
for (int i=;i<g[x].size();i++)
{
int y=g[x][i];
if (!dfn[y])
{
st.push((edge){x,i});
fa[y]=x;dfs(y);
chi++;
low[x]=min(low[x],low[y]);
if (low[y]>=dfn[x])
{
cut[x]=;
g[++t].clear();
while ()
{
int u=st.top().x,j=st.top().y;
int v=g[u][j]; st.pop();
if (be[u]!=t) {g[t].push_back(u); be[u]=t;}
if (be[v]!=t) {g[t].push_back(v); be[v]=t;}
if (u==x&&j==i) break;
}
}
}
else if (dfn[y]<dfn[x]&&fa[x]!=y)
{
st.push((edge){x,i});
low[x]=min(low[x],dfn[y]);
}
}
if (fa<&&chi==) cut[x]=;
} void dp(int x)
{
dfn[x]=root[h];
if (x<=n) w[x]=a[x]; else w[x]=;
s[x]=;
for (int i=; i<g[x].size(); i++)
{
int y=g[x][i];
if (!dfn[y])
{
dp(y);
w[x]=1ll*w[x]*w[y]%mo;
s[x]=(s[x]+w[y])%mo;
}
}
} int main()
{
freopen("1006.in","r",stdin);
freopen("1006.ans","w",stdout);
scanf("%d",&cas);
while (cas--)
{
scanf("%d%d",&n,&m);
for (int i=; i<=n; i++)
{
dfn[i]=fa[i]=cut[i]=be[i]=;
scanf("%d",&a[i]);
}
for (int i=; i<=m; i++)
{
scanf("%d%d",&x,&y);
g[x].push_back(y);
g[y].push_back(x);
}
t=n;
for (int i=; i<=n; i++)
if (!dfn[i])
{
h=;
dfs(i);
}
for (int i=; i<=n; i++) g[i].clear();
for (int i=n+; i<=t; i++)
for (int j=; j<g[i].size(); j++) {int x=g[i][j]; g[x].push_back(i);}
for (int i=; i<=t; i++) dfn[i]=f[i]=;
h=sum=;
for (int i=; i<=t; i++)
if (!dfn[i])
{
root[++h]=i;
dp(i);
sum=(sum+w[i])%mo;
}
for (int i=; i<=n; i++)
{
if (dfn[i]==i) f[i]=; else f[i]=1ll*w[dfn[i]]*quick(w[i])%mo;
f[i]=((ll)f[i]+sum-w[dfn[i]]+s[i]+mo)%mo;
}
int ans=;
for (int i=; i<=n; i++) ans=(ans+1ll*f[i]*i%mo)%mo;
printf("%d\n",ans);
for (int i=; i<=t; i++) g[i].clear();
}
return ;
}

hdu5739的更多相关文章

  1. [HDU5739]Fantasia(圆方树DP)

    题意:给一张无向点带有权无向图.定义连通图的权值为图中各点权的乘积,图的权值为其包含的各连通图的权和.设z_i为删除i点后图的权值,求$S = (\sum\limits_{i=1}^{n}i\cdot ...

  2. HDU5739 Fantasia【点双连通分量 割点】

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

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

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

  4. HDU5739 Fantasia 树形dp + 点双缩点

    这个题当时打多校的时候有思路,但是代码能力差,没有写出来 事后看zimpha巨巨的题解,看了觉得基本差不多 核心思路:就是找出割点,然后变成森林,然后树形dp就可以搞了 关键就在重新构图上,缩完点以后 ...

  5. [BZOJ5463][APIO2018]铁人两项(圆方树DP)

    题意:给出一张图,求满足存在一条从u到v的长度大于3的简单路径的有序点对(u,v)个数. 做了上一题[HDU5739]Fantasia(点双连通分量+DP),这个题就是一个NOIP题了. 一开始考虑了 ...

  6. PKUSC2018训练日程(4.18~5.30)

    (总计:共66题) 4.18~4.25:19题 4.26~5.2:17题 5.3~5.9: 6题 5.10~5.16: 6题 5.17~5.23: 9题 5.24~5.30: 9题 4.18 [BZO ...

随机推荐

  1. 2017Nowcoder Girl初赛重现赛

    https://ac.nowcoder.com/acm/contest/315#question A.平方数 代码: #include <bits/stdc++.h> using name ...

  2. ui-grid下拉过滤

    { field: 'TDK', displayName: 'TDK缺失与否', cellTemplate: `<div class="ui-grid-cell-contents&quo ...

  3. JConsole本地连接失败

    一.问题描述 笔者在使用JDK自带的JConsole小工具连接Myeclipse里面注册的MBean时,报如下错: 二.解决办法 添加JVM运行参数: -Dcom.sun.management.jmx ...

  4. VisualStudio2010项目转换为VisualStudio2005项目:解决方案和工程项目文件转换方法(2)

    因为我现在不喜欢把一篇博客写的很长很长,这篇博客是接着上一篇博客来写的.上一篇文章我很详细的说明了修改项目文件解决方案的过程.这篇文章我就说说项目中的项目文件该怎么修改.因为我平日里主要做的是ASP. ...

  5. JavaScript(二):对象、注释、事件!

    对象 JavaScript的一个重要功能就是面向对象的功能,通过基于对象的程序设计,可以用更直观.模块化和可重复使用的方式进行程序开发. 一组包含数据的属性和对属性中包含数据进行操作的方法,称为对象. ...

  6. 使用def文件简化dll导出

    原文链接地址:http://www.cnblogs.com/TianFang/archive/2013/05/04/3059073.html 在C++中,我们可以通过 __declspec(dllex ...

  7. 洛谷P4588 [TJOI2018]数学计算 【线段树】

    题目链接 洛谷P4588 题解 用线段树维护即可 #include<algorithm> #include<iostream> #include<cstring> ...

  8. taotao单点登录的用户Controller、service(注册、登录、验证是否登录方法)

    接口文档: 1.1. 注册接口 1.1.1. 检查数据是否可用 请求方法 GET URL http://sso.taotao.com/user/check/{param}/{type} 参数说明 格式 ...

  9. 通过 CLI 搭建 ghost

    参考: ghost 官网 系统架构说明 架构 架构说明 本实践将 web 接入, nodejs 服务, 数据库分离, 适合生产环境场景. nginx 接入请求, 反向代理后端 nodejs 服务 no ...

  10. C# 从服务器下载文件

    一.//TransmitFile实现下载 protected void Button1_Click(object sender, EventArgs e) { /* 微软为Response对象提供了一 ...