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

这题还用到了一个叫做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. (转) linux I/O优化 磁盘读写参数设置

    关于页面缓存的信息,可以用cat /proc/meminfo 看到.其中的Cached 指用于pagecache的内存大小(diskcache-SwapCache).随着写入缓存页,Dirty 的值会 ...

  2. springboot ueditor 使用心得

    1.将ueditor引入项目中会发现,图片不能上传,返回值意思是因配置文件错误,导致图片无法上传 默认情况是使用jsp初始配置文件,这就需要项目支持jsp解析 在maven中引入 <!--添加对 ...

  3. calendar components

    calendar components 日历 angular, react, vue ??? react https://github.com/intljusticemission/react-big ...

  4. spring笔记(二)

    共性问题: 1. 服务器启动报错,什么原因? * jar包缺少.jar包冲突 1) 先检查项目中是否缺少jar包引用 2) 服务器: 检查jar包有没有发布到服务器下: 用户库jar包,需要手动发布到 ...

  5. poj 2965 The Pilots Brothers' refrigerator (dfs)

    The Pilots Brothers' refrigerator Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 17450 ...

  6. P3032 [USACO11NOV]二进制数独Binary Sudoku

    题目描述 Farmer John's cows like to play an interesting variant of the popular game of "Sudoku" ...

  7. js金额转大写数字

    //金额转大写数字 const intToChinese = money => { //汉字的数字 let cnNums = new Array('零', '壹', '贰', '叁', '肆', ...

  8. HDU4725:The Shortest Path in Nya Graph(最短路)

    The Shortest Path in Nya Graph Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K ...

  9. BZOJ1040 骑士 基环外向树

    1040: [ZJOI2008]骑士 Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 6421  Solved: 2544[Submit][Status ...

  10. AWS CLI command example

    1.list ec2 instance-id, instance status, type, ip address, name aws ec2 describe-instances --query ' ...