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 ...
随机推荐
- 页面加载时给的子元素的第一个元素加class
HTML代码: <div id="xiao"> <ul> <li></li> </ul> </div> js ...
- javascript中将整数添加千位符号
如果num是整数的话,将其转换成带千位符号的字符串: Number(num).toString().replace(/(\d)(?=(\d{3})+(?!\d))/g, '$1' + ','); 另 ...
- VS 附加进程调试
1.在IIS 上新建一个项目,制定目录到 项目根目录. 2.制定IIS上指定 主机名称如: vk.com 3. 修改主机HOST 文件:C:\Windows\System32\drivers\etc ...
- 每个分组函数相当于一个for循环 将集合的变量不断遍历
每个分组函数相当于一个for循环 将集合的变量不断遍历
- 【bzoj3653】谈笑风生 DFS序+树状数组
题目描述 给出一棵以1为根的有根树,q次询问,每次询问给出a和k,求点对 (b,c) 的数目,满足:a.b.c互不相同,b与a距离不超过k,且a和b都是c的祖先. 输入 输入文件的第一行含有两个正整数 ...
- DataBase -- Second Highest Salary
Question: Write a SQL query to get the second highest salary from the Employee table. +----+-------- ...
- 淡入淡出效果的js原生实现
淡入淡出效果,在日常项目中经常用到,可惜原生JS没有类似的方法,而有时小的页面并不值得引入一个jQuery库,所以就自己写了一个,已封装, 有用得着的朋友, 可以直接使用. 代码中另附有一个设置元素透 ...
- Win7命令mklink的使用
C盘空间越来越小,在Win7里还标红了,心里看得不舒服,得想一些方法腾出一些空间.看了AppData,Chrome占了1G多的空间. 当时安装Chrome浏览器时因为不能指定安装目录,所以Chrome ...
- AWS CLI command example
1.list ec2 instance-id, instance status, type, ip address, name aws ec2 describe-instances --query ' ...
- C++中的各种“神奇”东西
将光标放到任意的位置 void gotoxy(int x,int y)//位置函数 { COORD pos; pos.X=x; pos.Y=y; SetConsoleCursorPosition(Ge ...