可以将这个图转换成森林来进行树形dp求解。看了这篇具体教学才会的:http://www.cnblogs.com/WABoss/p/5696926.html

大致思路:求解一下点双连通分量(Tarjan),新构造一个节点连向这个分量中每一个节点。每个点双连通分量都这样构造好之后,原本连通的一张图就形成了一棵树,并且这个树中拿掉一个节点之后的连通性和原图相同!因此,可以在树上求解答案(树dp即可)。

注意:数据不一定保证原图是连通的,所以要特别注意原图中单个点的情况。

#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<vector>
#include<map>
#include<set>
#include<queue>
#include<stack>
#include<iostream>
using namespace std;
typedef long long LL;
void File()
{
freopen("D:\\in.txt","r",stdin);
freopen("D:\\out.txt","w",stdout);
}
inline int read()
{
char c = getchar(); while(!isdigit(c)) c = getchar();
int x = ;
while(isdigit(c)) { x = x * + c - ''; c = getchar(); }
return x;
} const int maxn=;
const LL mod=1e9+; int h[maxn],tot;
struct X { int u,v,nx; }e[*maxn]; int pre[maxn],dfs_clock,low[maxn],bcc_cnt,bccno[maxn]; struct Edge
{
int u,v;
Edge(int from,int to) { u=from; v=to; }
};
stack<Edge> S;
vector<int>bcc[maxn]; int T,n,m,be[*maxn],block,sz,cnt[maxn];
bool f[maxn];
LL w[*maxn],ans[maxn],val[maxn],SUM,pru[*maxn]; int head[*maxn];
struct Tree{ int u,v,nx; }tree[*maxn];
int id; LL extend_gcd(LL a,LL b,LL &x,LL &y)
{
if(a==&&b==) return -;
if(b==){x=;y=;return a;}
LL d=extend_gcd(b,a%b,y,x);
y-=a/b*x;
return d;
} LL mod_reverse(LL a)
{
LL x,y;
LL d=extend_gcd(a,mod,x,y);
if(d==) return (x%mod+mod)%mod;
else return -;
} void ADD(int a,int b)
{
tree[tot].u=a, tree[tot].v=b, tree[tot].nx=head[a], head[a]=tot++;
} void AddEdge(int a,int b)
{
e[tot].u=a, e[tot].v=b, e[tot].nx=h[a], h[a]=tot++;
} int Tarjan(int u,int fa)
{
int lowu=pre[u]=++dfs_clock;
for(int i=h[u];i!=-;i=e[i].nx)
{
int v=e[i].v;
Edge e = Edge(u,v);
if(!pre[v])
{
S.push(e);
int lowv=Tarjan(v,u); lowu=min(lowv,lowu);
if(lowv>=pre[u])
{
bcc_cnt++; id++; w[id]=;
for(;;)
{
Edge x = S.top();S.pop();
if(bccno[x.u]!=bcc_cnt) {
ADD(x.u,id); ADD(id,x.u); be[id]=x.u; bccno[x.u]=bcc_cnt;
} if(bccno[x.v]!=bcc_cnt) {
ADD(x.v,id); ADD(id,x.v); be[id]=x.v; bccno[x.v]=bcc_cnt;
} if(x.u==u&&x.v==v) break;
}
}
}
else if(pre[v]<pre[u]&&v!=fa) { S.push(e); lowu=min(lowu,pre[v]); }
}
return lowu;
} void find_bcc()
{
memset(pre,,sizeof(pre));
memset(bccno,,sizeof(bccno));
dfs_clock=bcc_cnt=;
for(int i=;i<=n;i++) if(!pre[i]) Tarjan(i,-);
} void dfs(int x)
{
sz++; f[x]=; be[x]=block;
for(int i=h[x];i!=-;i=e[i].nx) if(!f[e[i].v]) dfs(e[i].v);
} void dp(int x)
{
f[x]=; pru[x]=w[x]; LL s=;
for(int i=head[x];i!=-;i=tree[i].nx)
{
if(f[tree[i].v]) continue;
dp(tree[i].v); pru[x]=(pru[x]*pru[tree[i].v])%mod;
s=(s+pru[tree[i].v])%mod;
}
s=(s+val[be[x]]*mod_reverse(pru[x])%mod)%mod;
ans[x]=((SUM-val[be[x]]+mod)%mod+s)%mod;
} int main()
{
scanf("%d",&T);
while(T--)
{
scanf("%d%d",&n,&m);
for(int i=;i<=n;i++) w[i]=(LL)read(); memset(h,-,sizeof h); tot=;
for(int i=;i<=m;i++) {
int u=read(),v=read(); AddEdge(u,v); AddEdge(v,u);
} memset(f,block=sz=,sizeof f);
for(int i=;i<=n;i++)
{
if(f[i]) continue;
block++; sz=; dfs(i); cnt[block]=sz;
} SUM=;
for(int i=;i<=block;i++) val[i]=;
for(int i=;i<=n;i++) val[be[i]]=(val[be[i]]*w[i])%mod;
for(int i=;i<=block;i++) SUM=(SUM+val[i])%mod; memset(head,-,sizeof head); tot=; id=n;
find_bcc(); memset(f,,sizeof f);
for(int i=;i<=n;i++)
if(cnt[be[i]]==) ans[i]=(SUM-val[be[i]]+mod)%mod;
for(int i=n+;i<=id;i++) if(!f[i]) dp(i); LL S=;
for(int i=;i<=n;i++) S=(S+((LL)i*ans[i])%mod)%mod;
printf("%lld\n",S);
}
return ;
}

HDU 5739 Fantasia的更多相关文章

  1. HDU 5739 Fantasia 双连通分量 树形DP

    题意: 给出一个无向图,每个顶点有一个权值\(w\),一个连通分量的权值为各个顶点的权值的乘积,一个图的权值为所有连通分量权值之和. 设删除顶点\(i\)后的图\(G_i\)的权值为\(z_i\),求 ...

  2. hdu 5739 割点

    Fantasia Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total S ...

  3. HDU5739 Fantasia(点双连通分量 + Block Forest Data Structure)

    题目 Source http://acm.hdu.edu.cn/showproblem.php?pid=5739 Description Professor Zhang has an undirect ...

  4. HDOJ 2111. Saving HDU 贪心 结构体排序

    Saving HDU Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total ...

  5. 【HDU 3037】Saving Beans Lucas定理模板

    http://acm.hdu.edu.cn/showproblem.php?pid=3037 Lucas定理模板. 现在才写,noip滚粗前兆QAQ #include<cstdio> #i ...

  6. hdu 4859 海岸线 Bestcoder Round 1

    http://acm.hdu.edu.cn/showproblem.php?pid=4859 题目大意: 在一个矩形周围都是海,这个矩形中有陆地,深海和浅海.浅海是可以填成陆地的. 求最多有多少条方格 ...

  7. HDU 4569 Special equations(取模)

    Special equations Time Limit:1000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u S ...

  8. HDU 4006The kth great number(K大数 +小顶堆)

    The kth great number Time Limit:1000MS     Memory Limit:65768KB     64bit IO Format:%I64d & %I64 ...

  9. HDU 1796How many integers can you find(容斥原理)

    How many integers can you find Time Limit:5000MS     Memory Limit:32768KB     64bit IO Format:%I64d ...

随机推荐

  1. window.showModalDialog()的简单用法

    //创建一个显示html内容的模态对话框: vReturnValue = window.showModalDialog(sURL [, vArguments] [,sFeatures]) //创建一个 ...

  2. 基于QTcpSocket和QTcpServer的Tcp通讯以及QDataStream序列化数据

    最近要在QT下开发Tcp通讯,发送序列化数据以便于接收. 这里涉及到几个问题: 1.QTcpSocket.QTcpServer的通讯 2.QDataStream序列化数据 多的不说,直接上干货!!! ...

  3. mysql表备份及还原

    备份 导出数据库所有表结构 ? 1 mysqldump -uroot -ppassword -d dbname > db.sql 导出数据库某个表结构 ? 1 mysqldump -uroot ...

  4. CSS的基本概念

    <!--CSS 一.概念:CSS的全称是Cascading Style Sheets,层叠样式表,用来控制HTML标签样式,在美化网页中起到非常重要的作用 CSS的编写格式是键值对形式的,比如 ...

  5. 移动端日历控件 mobiscroll 的简单使用、参数设置

    mobiscroll 在性能方面比较好,可选用多种效果,滑动效果也比较顺畅.   提供样式文件和js文件,直接点击下载,该版本是 mobiscroll 2.13的 官方地址 :https://docs ...

  6. UVALive - 3026 Period kmp next数组的应用

    input n 2<=n<=1000000 长度为n的字符串,只含小写字母 output Test case #cas 长度为i时的最小循环串 循环次数(>1) 若没有则不输出 做法 ...

  7. UIDynamic物理仿真

    UIDynamic是从iOS 7开始引入的一种新技术,隶属于UIKit框架可以认为是一种物理引擎,能模拟和仿真现实生活中的物理现象, 比如重力.弹性碰撞等现象,UIKit动力具有可组合.可重用和声明式 ...

  8. github 上传项目基本步骤

    说来也惭愧,我是最近开始用github,小白一个,昨天研究了一个下午.终于可以上传了,所以今天写点,一来分享是自己的一些经验,二来也是做个记录,万一哪天又不记得了:) 废话不多说,直接来,这次主要介绍 ...

  9. 《C++ Primer》之面向对象编程(一)

    面向对象编程基于三个基本概念:数据抽象.继承和动态绑定.//动态绑定使编译器能够在运行时决定是使用基类中定义的函数还是派生类中定义的函数. 面向对象编程的关键思想是多态性(polymorphism). ...

  10. UI篇—UITableview

    一.基本介绍 在众多移动应⽤用中,能看到各式各样的表格数据 . 在iOS中,要实现表格数据展示,最常用的做法就是使用UITableView,UITableView继承自UIScrollView,因此支 ...