HDU 5739(点双连通)
来源:互联网 发布:淘宝联盟互刷 编辑:程序博客网 时间:2024/03/29 04:08
题目大意:给定一个无向图,对于每个连通分量的权值为其中点的权值乘积,而整个无向图的权值为所以连通分量的权值和。Gi表示删除点i,图的权值,求sum(i*Gi)%(10e+7)
显然只有删除割点才会改变图的连通性,但我也没有想到怎么解决,这里根据官方题解
显然, 只要删掉关键点才会使图不联通. 对于其他点, 权值很容易计算.
首先求出所有的点双联通分量, 对于每一个点双联通分量SSS, 新建一个节点sss, 向SSS中每个节点vvv连边. 这样一来, 新增的点和原来图中的点会构成一个森林(据说这个有个名字, block forest data structure). 很容易观察到, 叶子节点肯定都是非关键点, 内部节点要么是关键点, 要么是新增的节点.
对于这个森林FFF, 删掉一个关键点或者一个叶子iii之后, 会得到一个新森林FiF_iFi, 这个FiF_iFi对应的连通块集合和GiG_iGi对应的连通块集合其实是一样的(不考虑那些新增的点). 显然GiG_iGi的权值和FiF_iFi的权值也是一样的,FiF_iFi的权值我们很容易通过树形dp算出来, 那么GiG_iGi的权值也随之而出.
根据对应性质,先求出点双连通分量,再进行树形dp即可。开始求点双连通时用了vector超时,改了就没问题了。
#include <iostream>#include <cstdio>#include <cstring>#include <cmath>#include <algorithm>#include <vector>#include <stack>#include <queue>#include <map>#include <ctime>using namespace std;#define ll long longconst int maxn=800005;const ll mod=1000000007;ll pri[maxn];int head[maxn];int to[maxn],ne[maxn],from[maxn];int cot;inline void addedge(int u,int v){ from[cot]=u; to[cot]=v; ne[cot]=head[u]; head[u]=cot++;}int head1[maxn];int to1[maxn];int ne1[maxn];int cot1;inline void addEdge(int u,int v){ to1[cot1]=v; ne1[cot1]=head1[u]; head1[u]=cot1++;}ll pow_mod(ll a,ll b){ ll res=1; while(b){ if(b&1)(res*=a)%=mod; (a*=a)%=mod; b>>=1; } return res;}int dfn[maxn];int dfs_cot;int bcc_cot;int st[maxn];int top;bool vis[maxn];int dfs(int u,int fa){ vis[u]=true; int lowu=dfn[u]=++dfs_cot; for(int i=head[u];~i;i=ne[i]){ int v=to[i]; if(!vis[v]){ st[top++]=i; int lowv=dfs(v,u); lowu=min(lowv,lowu); if(lowv>=dfn[u]){ bcc_cot++; //printf("bcc[%d]:\n",bcc_cot); for(;;){ if(top==0)break; int e=st[--top]; //printf("e[%d]:%d %d\n",e,from[e],to[e]); //if(bcc_id[from[e]]!=bcc_cot)printf("push:%d\n",from[e]); addEdge(bcc_cot,from[e]); addEdge(from[e],bcc_cot); //if(bcc_id[to[e]]!=bcc_cot)printf("push:%d\n",to[e]); addEdge(bcc_cot,to[e]); addEdge(to[e],bcc_cot); pri[bcc_cot]=1; if(from[e]==u&&to[e]==v)break; } } } else if(dfn[v]<dfn[u]&&v!=fa){ st[top++]=i; lowu=min(lowu,dfn[v]); } } return lowu;}void init(int n){ bcc_cot=n; top=0; cot=0; dfs_cot=0; cot1=0; memset(head1,-1,sizeof(head1)); memset(head,-1,sizeof(head)); memset(vis,0,sizeof(vis));}ll sum[maxn];ll product[maxn];void dp_dfs(int u,int fa){ vis[u]=true; sum[u]=0; product[u]=pri[u]; for(int i=head1[u];~i;i=ne1[i]){ int v=to1[i]; if(v==fa)continue; if(!vis[v]){ dp_dfs(v,u); sum[u]=(sum[u]+product[v])%mod; product[u]=(product[v]*product[u])%mod; } }}void dp(int u,int fa){ dfn[u]=1; if(fa!=0){ int tmp=product[fa]*pow_mod(product[u],mod-2)%mod; sum[u]=(sum[u]+tmp)%mod; product[u]=product[fa]; } for(int i=head1[u];~i;i=ne1[i]){ int v=to1[i]; if(!dfn[v]){ dp(v,u); } }}int main(){ int t,n,m; int u,v; scanf("%d",&t); while(t--){ scanf("%d %d",&n,&m); init(n); for(int i=1;i<=n;i++){ scanf("%lld",&pri[i]); pri[i]%=mod; } cot=0; for(int i=0;i<m;i++){ scanf("%d %d",&u,&v); addedge(u,v); addedge(v,u); } for(int i=1;i<=n;i++){ if(!vis[i])dfs(i,0); } memset(vis,0,sizeof(vis)); memset(dfn,0,sizeof(dfn)); ll ans=0; for(int i=1;i<=n;i++){ if(!vis[i]){ dp_dfs(i,0); dp(i,0); (ans+=product[i])%=mod; } }/* for(int i=1;i<=bcc_cot;i++){ printf("sum[%d]:%lld\n",i,sum[i]); printf("pro[%d]:%lld\n",i,product[i]); } printf("ans:%lld\n",ans);*/ ll fans=0; for(int i=1;i<=n;i++){ (fans+=(i*(ans+sum[i]-product[i]+mod))%mod)%=mod; } printf("%lld\n",fans); } return 0;}
0 0
- hdu 5739(点双连通)
- HDU 5739(点双连通)
- HDU 5739 (点双连通 树DP)
- hdu 3749 点双连通
- hdu 3394(点双连通)
- 【HDU 5739】Fantasia(点双连通+dfs)
- HDU 5409 双连通缩点
- HDU 5739 Fantasia(点双连通分量+树形DP)
- hdu 5739 点双连通分量+乘法逆元超详细讲解
- hdu - 4338 - Simple Path - 割点 && 双连通
- HDU 4338 Simple Path 点双连通+lca
- HDU -- 3844 Mining Your Own Business(点双连通)
- HDU 4005 The war(边双连通+缩点)
- 点双连通 练习
- hdu 3686 点双连通 按<割点>缩点 + 倍增lca
- hdu 4005(双连通)
- hdu 4005 双连通
- 【HDU】3394 Railway 点双连通求块
- 输入年月 返回当前月份的天数
- 60. Permutation Sequence
- 前端工程师面试指南
- win10 64位免安装版mysql-5.7.16-winx64安装步骤
- Host 'XXX' is not allowed to connect to this MySQL server 解决方案
- HDU 5739(点双连通)
- UIP协议栈UDP数据发送的问题
- 数据结构课程设计-图书管理开发系统
- 网络程序设计课程学习心得总结
- 联想手机权限开启方法3
- HTML基础
- 为什么抛硬币只会出现三种情况?
- 大神博客,膜拜
- pcl1.8.0+QT5.7.0+vs2013 win7 x64环境配置以及第一个小程序实现