简化一下题意,我们先看成一副强连通的图,这时候应该是最简单了,去点任意点都是其他的乘积。那再加强一点难度,改为两个强连通图连接的非强连通图呢?那应该就是找出关键的那个点,并求出两边的乘积。但是一个一个去找是不可能的。

假设如图中的非绿色线是题目给的图。然后我们根据强连通分量去新建一副如图中绿色线条的图,那么这时候我们就把原图转化为以可树了。。对于每一个点我们求的是该点以及以下的乘积。然后我们从A出发这时候我们发现A点的值刚好就是整幅图的乘积。这时候如果我们需要求删除3这个点的得到的结果应该就是整一副图去除以3点及一下的乘积得到1,2的乘积,再加上3点的子树的乘积和也就是4、5 和 6、7的乘积和。

这道题目的难点就是转化建图的那一个步骤,应该说是最核心的部分。

  1. #include<bits/stdc++.h>
  2. #define LL long long
  3. using namespace std;
  4.  
  5. const int maxn = 1e5 + ;
  6. const LL mod = 1e9 + ;
  7.  
  8. LL n, w[maxn], vis[maxn << 1], sum[maxn << 1], pro[maxn << 1];
  9.  
  10. struct oldEdge{
  11. int v, next;
  12. bool flag;
  13. };
  14. int oldHead[maxn], ocnt;
  15. oldEdge oedge[maxn << ];
  16.  
  17. void addOldEdge(int u, int v){
  18. oedge[ocnt].v = v;
  19. oedge[ocnt].flag = false;
  20. oedge[ocnt].next = oldHead[u];
  21. oldHead[u] = ocnt ++;
  22. }
  23.  
  24. struct newEdge{
  25. int v, next;
  26. };
  27. int newHead[maxn << ], ncnt;
  28. newEdge nedge[maxn << ];
  29.  
  30. void addNewEdge(int u, int v){
  31. nedge[ncnt].v = v;
  32. nedge[ncnt].next = newHead[u];
  33. newHead[u] = ncnt ++;
  34. }
  35.  
  36. int dfn[maxn], low[maxn], root[maxn], rn, cnt;
  37. stack<int>sta;
  38.  
  39. void tarjan(int u, int fa){
  40. dfn[u] = low[u] = ++cnt;
  41. for(int i = oldHead[u]; i != -; i = oedge[i].next){
  42. if(oedge[i].flag) continue;
  43. oedge[i].flag = oedge[i ^ ].flag = true;
  44. sta.push(i);
  45. int v = oedge[i].v;
  46.  
  47. if(dfn[v]){
  48. low[u] = min(low[u], dfn[v]);
  49. continue;
  50. }
  51. tarjan(v, fa);
  52. low[u] = min(low[u], low[v]);
  53.  
  54. if(low[v] >= dfn[u]){
  55. rn ++;
  56. int ek;
  57. do{
  58. ek = sta.top();sta.pop();
  59. root[oedge[ek].v] = root[oedge[ek ^ ].v] = fa;
  60. addNewEdge(rn, oedge[ek].v); addNewEdge(oedge[ek].v, rn);
  61. addNewEdge(rn, oedge[ek ^ ].v); addNewEdge(oedge[ek ^ ].v, rn);
  62. }while(oedge[ek ^ ].v != u);
  63. }
  64. }
  65. }
  66.  
  67. void dfs(int u){
  68. vis[u] = true;
  69. sum[u] = ;
  70. pro[u] = (u <= n) ? w[u] : ;
  71. for(int i = newHead[u]; i != -; i = nedge[i].next){
  72. int v = nedge[i].v;
  73. if(vis[v]) continue;
  74. dfs(v);
  75. if(u <= n)
  76. sum[u] = (sum[u] + pro[v]) % mod;
  77. pro[u] = pro[u] * pro[v] % mod;
  78. }
  79. }
  80.  
  81. LL inv(LL a){
  82. int p = mod - ;
  83. LL ret = ;
  84. while(p){
  85. if(p & )ret = ret * a % mod;
  86. a = a * a % mod;
  87. p >>= ;
  88. }
  89. return ret;
  90. }
  91.  
  92. void init(){
  93. memset(root, , sizeof(root));
  94. memset(newHead, -, sizeof(newHead));
  95. memset(oldHead, -, sizeof(oldHead));
  96. memset(dfn, , sizeof(dfn));
  97. memset(vis, false, sizeof(vis));
  98. ncnt = ocnt = cnt = ;
  99. }
  100.  
  101. int main(){
  102. int T, m, a, b;scanf("%d",&T);
  103. while(T --){
  104. scanf("%lld%d",&n,&m);
  105. init();rn = n;
  106. for(int i = ; i <= n; i ++)scanf("%lld",&w[i]);
  107. for(int i = ; i < m; i ++){
  108. scanf("%d%d",&a,&b);
  109. addOldEdge(a,b);
  110. addOldEdge(b,a);
  111. }
  112. for(int i = ; i <= n; i ++)
  113. if(!dfn[i])tarjan(i, rn + );
  114.  
  115. LL tot = ;
  116. for(int i = ; i <= n; i ++){
  117. if(vis[i]) continue;
  118. if(root[i]){
  119. dfs(root[i]);
  120. tot = (tot + pro[root[i]]) %mod;
  121. }else
  122. tot = (tot + w[i]) % mod;
  123. }
  124. LL ans = ;
  125. for(int i = ; i <= n; i ++){
  126. if(root[i]){
  127. LL temp = ((tot - pro[root[i]] + pro[root[i]] * inv(pro[i]) + sum[i]) % mod + mod) * i % mod;
  128. ans = (ans + temp) % mod;
  129. }
  130. else
  131. ans = ((ans + (tot - w[i]) * i) % mod + mod) % mod;
  132. }
  133. printf("%lld\n",ans);
  134. }
  135. return ;
  136. }

Fantasia (点强连通分量建图 + 树形DP)的更多相关文章

  1. bzoj 4871: [Shoi2017]摧毁“树状图” [树形DP]

    4871: [Shoi2017]摧毁"树状图" 题意:一颗无向树,选两条边不重复的路径,删去选择的点和路径剩下一些cc,求最多cc数. update 5.1 : 刚刚发现bzoj上 ...

  2. 【HDU5934】Bomb——有向图强连通分量+重建图

    题目大意 二维平面上有 n 个爆炸桶,i−thi-thi−th爆炸桶位置为 (xi,yi)(x_i, y_i)(xi​,yi​) 爆炸范围为 rir_iri​ ,且需要 cic_ici​ 的价格引爆, ...

  3. 强连通 反向建图 hdu3639

    Hawk-and-Chicken Time Limit: 6000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) ...

  4. poj1949Chores(建图或者dp)

    /* 题意:n个任务,有某些任务要在一些任务之前完成才能开始做! 第k个任务的约束只能是1...k-1个任务!问最终需要最少的时间完成全部的 任务! 思路:第i个任务要在第j个任务之前做,就在i,j之 ...

  5. 深探树形dp

    看到同学在写一道树形dp,好奇直接拿来写,发现很不简单. 如图,看上去是不是很像选课,没错这不是选课,升级版吧,多加了点东西罢了.简单却调了一晚上和一上午. 思路:很简单强联通分量+缩点+树形dp.直 ...

  6. Tarjan算法 求 有向图的强连通分量

    百度百科 https://baike.baidu.com/item/tarjan%E7%AE%97%E6%B3%95/10687825?fr=aladdin 参考博文 http://blog.csdn ...

  7. poj 2186 tarjan求强连通分量

    蕾姐讲过的例题..玩了两天后才想起来做 貌似省赛之后确实变得好懒了...再努力两天就可以去北京玩了! 顺便借这个题记录一下求强连通分量的算法 1 只需要一次dfs 依靠stack来实现的tarjan算 ...

  8. POJ 3107.Godfather 树形dp

    Godfather Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 7536   Accepted: 2659 Descrip ...

  9. Tarjan算法初探 (1):Tarjan如何求有向图的强连通分量

    在此大概讲一下初学Tarjan算法的领悟( QwQ) Tarjan算法 是图论的非常经典的算法 可以用来寻找有向图中的强连通分量 与此同时也可以通过寻找图中的强连通分量来进行缩点 首先给出强连通分量的 ...

随机推荐

  1. 《Mysql DML语句》

    1:DISTINCT 用于去重,但是需要注意的是,它是用于所有列的,也就是说,除非指定的列全部相同,否则所有的行都会被检索出来. 2:ORDER BY 用于排序,但是应该注意的是,它因该是 SELEC ...

  2. 20165225《Java程序设计》第六周学习总结

    20165225<Java程序设计>第六周学习总结 1.视频与课本中的学习: - 第八章学习总结 String类 String对象(常量,对象) 字符串并置(结果仍是常量) 常用方法 le ...

  3. Python pip 如何升级

    场景:部署环境时,在线安装第三方库(pip install flask-bootstrap),提示pip版本过低. 解决方法一:        命令: python -m pip install -- ...

  4. zabbix宏(macro)使用:自定义监控阈值

    一.简单应用场景 zabbix在监控cpu load时并没有考虑客户端cpu的个数和核心数量,当平均5分钟的负载达到5时zabbix执行报警动作,这样是非常不合理的,笔者的被监控机器有四核和单核,现在 ...

  5. IGMP协议

    IGMP报文格式: 4bit的IGMP版本(1)+4bit的IGMP类型(1-2)+8bit未用+16bit检验和(同ICMP)+32bit组地址(D类IP地址) 类型为1说明是由多播路由器发出的查询 ...

  6. 【JMeter】【微信好文收藏】Jmeter接口测试实战-有趣的cookie

    场景: 接口测试时常都需要登录,请求方式(post), 登录常用的方法有通过获取token, 获取session, 获取cookie, 等等. 这几种都有一个共同的特点, 有效期(expires). ...

  7. innodb_flush_method理解【转】

    innodb_flush_method这个参数控制着innodb数据文件及redo log的打开.刷写模式,对于这个参数,文档上是这样描述的: 有三个值:fdatasync(默认),O_DSYNC,O ...

  8. 前端 CSS 三种引入方式

    CSS三种引入方式 行内样式 内接样式 外部样式 链接式 导入式 行内样式 就是在标签加上style属性设置样式 <!DOCTYPE html> <html lang="e ...

  9. UE4程序及资源加密保护方案

    UnrealEngine4外壳加密 . Virbox Protector 解决代码反汇编和反dump代码,解决软件盗版与算法抄袭. 虚幻引擎4是由游戏开发者为开发游戏而制作的.完整的游戏开发工具套件. ...

  10. abap method中的异常处理

    1: 抛出异常 2: 处理异常