hdu5739
以前从来没写过求点双连通分量,现在写一下……
这题还用到了一个叫做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的更多相关文章
- [HDU5739]Fantasia(圆方树DP)
题意:给一张无向点带有权无向图.定义连通图的权值为图中各点权的乘积,图的权值为其包含的各连通图的权和.设z_i为删除i点后图的权值,求$S = (\sum\limits_{i=1}^{n}i\cdot ...
- HDU5739 Fantasia【点双连通分量 割点】
HDU5739 Fantasia 题意: 给出一张\(N\)个点的无向图\(G\),每个点都有权值\(w_i\),要求计算\(\sum_{i=1}^{N}i\cdot G_i % 1e9+7\) 其中 ...
- HDU5739 Fantasia(点双连通分量 + Block Forest Data Structure)
题目 Source http://acm.hdu.edu.cn/showproblem.php?pid=5739 Description Professor Zhang has an undirect ...
- HDU5739 Fantasia 树形dp + 点双缩点
这个题当时打多校的时候有思路,但是代码能力差,没有写出来 事后看zimpha巨巨的题解,看了觉得基本差不多 核心思路:就是找出割点,然后变成森林,然后树形dp就可以搞了 关键就在重新构图上,缩完点以后 ...
- [BZOJ5463][APIO2018]铁人两项(圆方树DP)
题意:给出一张图,求满足存在一条从u到v的长度大于3的简单路径的有序点对(u,v)个数. 做了上一题[HDU5739]Fantasia(点双连通分量+DP),这个题就是一个NOIP题了. 一开始考虑了 ...
- 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 ...
随机推荐
- WCF扩展记录服务调用时间
WCF 提供了许多扩展点供开发人员自定义运行时行为. WCF 在 Channel Layer 之上还提供了一个高级运行时,主要是针对应用程序开发人员.在 WCF 文档中,它常被称为服务模型层(Serv ...
- JSON教程(1)
JSON:JavaScript对象表示发即JavaScript Object Notation. JSON是存储和交换文本信息的语法.类似XML. JSON比XML更小,更快,更易解析. { &quo ...
- 【题解】NOI2015寿司晚宴
想好久啊+不敢写啊……但果然人还是应当勇敢自信,只有坚定地去尝试,才会知道最后的结果.1A真的太开心啦,不过好像我的做法还是比较复杂的样子……理解起来应该算是比较容易好懂的类型,大家可以参考一下思路~ ...
- [Leetcode] Remove duplicates from sorted list 从已排序的链表中删除重复元素
Given a sorted linked list, delete all duplicates such that each element appear only once. For examp ...
- underscore的bind和bindAll方法
bind方法和bindAll方法都是用来设定函数的this值的,区别是调用方式不同. var xiaoming = { say:function(){ console.log('I am xiaomi ...
- git查看和操作commit命令
git reflog 显示所有branch的commit,包括commit和reset,以及已删除的commit.而git log只显示当前branch的commit,不包括已删除的commit gi ...
- ext大法好啊
http://www.cnblogs.com/keshuqi/p/6257895.html
- Dubbo入门介绍---搭建一个最简单的Demo框架
Dubbo入门---搭建一个最简单的Demo框架 置顶 2017年04月17日 19:10:44 是Guava不是瓜娃 阅读数:320947 标签: dubbozookeeper 更多 个人分类: D ...
- 使用adobe pdf去除PDF文档中的批量雷同文本
一.问题的提出 MgoSoft tiff to pdf软件没有提供中国地区的非VISA用户的购买渠道,中国通常都是银联标识走天下,卡不是VISA买不了这样的软件, 那么, MgoSoft tiff t ...
- 使用jQuery发送POST,Ajax请求返回JSON格式数据
问题: 使用jQuery POST提交数据到PHP文件, PHP返回的json_encode后的数组数据,但jQuery接收到的数据不能解析为JSON对象,而是字符串{"code" ...