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

这题还用到了一个叫做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. 基于bootstrap动态分页

    bootstrap本身的分页有分页组件 但是却是静态的,无法满足要求,分页必须根据当前的总页数来展示 使用插件bootstrap-paginator github下载地址 https://github ...

  2. ARC075 F.Mirrored

    题目大意:给定D,询问有多少个数,它的翻转减去它本身等于D 题解做法很无脑,利用的是2^(L/2)的dfs,妥妥超时 于是找到了一种神奇的做法. #include <iostream> u ...

  3. Codeforces Round #392 (div.2) E:Broken Tree

    orz一开始想不画图做这个题(然后脑袋就炸了,思维能力有待提高) 我的做法是动态规划+贪心+构造 首先把题目给的树变成一个可行的情况,同时weight最小 这个可以通过动态规划解决 dp[x]表示以x ...

  4. [bzoj3886] [USACO15JAN]电影移动Moovie Mooving

    题目链接 状压\(dp\). 注意到\(n\leq 20\)且每个只能用一次,所以很显然可以压缩每部电影看过没,记\(f[sta]\)为状态为\(sta\)时最多可以看多久. 转移时先枚举状态,然后枚 ...

  5. GYM - 100814 C.Connecting Graph

    题意: 初始有n个点,m次操作.每次操作加一条边或者询问两个点第一次连通的时刻(若不连通输出-1). 题解: 用并查集维护每个点所在连通块的根.对于每次加边,暴力的更新新的根. 每次将2个块合并时,将 ...

  6. 在iis上部署ssl证书 https

    1.取走证书下载下来的文件.解压iis的压缩包. 2.打开internet信息服务iis管理器 3.双击打开后,选择导入,导入我们刚刚解压得到的pfx文件,这个pfx文件就是你需要部署域名的那个文件. ...

  7. 处理WebService asmx的经验

    项目的需求,需要和一个.net系统进行数据交换,合作方提供了一个WebService接口.这个与一般的PHP POST或GET传值再查库拿数据的思路有点不一样,需要用到SOAP模块,处理方法也很简单, ...

  8. GROUP_CONCAT(expr)

    This function returns a string result with the concatenated non-NULL values from a group. It returns ...

  9. Fabric证书解析

    一.证书目录解析   通过cryptogen生成所有证书文件后,以peerOrgannizations的第一个组织树org1为例,每个目录和对应文件的功能如下:   ca: 存放组织的根证书和对应的私 ...

  10. 如何打开小米,oppo,华为等手机的系统应用的指定页面

    如题,拿Oppo 手机做个示例,小米 华为也是如此. 在编写Android应用的时候,我们经常会有这样的需求,我们想直接打开系统应用的某个页面.比如在Oppo R9 手机上我们想打开某个应用的通知管理 ...