首页 > 其他分享 >P4630 [APIO2018] 铁人两项 题解

P4630 [APIO2018] 铁人两项 题解

时间:2023-06-27 17:23:00浏览次数:40  
标签:P4630 cc 题解 APIO2018 back ++ int low push

一、题目描述:

  给你一个 $n$ 个点,$m$ 条边的无向图。图不一定联通

  求出点对 $( u,c,v )$ 的数量,使得点 $u$ 存在一条经过点 $c$ 到达点 $v$ 的无向图。

  数据范围:$1 \le n \le 1 \times 10^5,1 \le m \le 2 \times 10^5$


 二、解题思路:

  算是圆方树比较模板的题了吧。

  首先化成树/森林,有环的话不好统计。

  考虑固定两个点,求中间点的个数。

  很明显同一个环上的任意两点可以通过环上其其它任意点到达彼此。

  如果两个点的路径上有环则这个环上的所有点都可以作为中间点。

  感觉就是求路径上方点的度数了,但是出现每个点会重复统计统计在两个方点内。

  所以我们可以将圆点值赋为 $-1$,将方点的权值赋为它的度数。刚好也消除掉两个端点带来的影响。

  于是转化为统计圆方树上任意两圆点之间的路径权值和,经典问题了。时间复杂度 $O(n+m)$。


 三、完整代码:

 1 #include<iostream>
 2 #include<vector>
 3 #define N 200010
 4 using namespace std;
 5 long long ans;
 6 int n,m,r,cc,tot;
 7 vector <int> e1[N],e2[N];
 8 int s[N],res[N],vis1[N],vis2[N];
 9 int q[N],du[N],dfn[N],low[N],val[N];
10 void tarjan(int u)
11 {
12     dfn[u]=low[u]=++tot;q[++r]=u;
13     for(int to:e1[u])
14     {
15         if(!dfn[to]){
16             tarjan(to),low[u]=min(low[u],low[to]);
17             if(low[to]>=dfn[u]){
18                 cc++;du[cc]+=2;
19                 du[to]++,du[u]++;
20                 e2[cc].push_back(u);
21                 e2[u].push_back(cc);
22                 e2[cc].push_back(to);
23                 e2[to].push_back(cc);
24                 while(q[r]^to){
25                     e2[cc].push_back(q[r]);
26                     e2[q[r]].push_back(cc);
27                     du[q[r]]++,du[cc]++;r--;
28                 }r--;
29                 //弹栈的时候不要把 u 也弹出来了 
30             }
31         }else low[u]=min(low[u],dfn[to]);
32     }
33 }
34 void dfs1(int u,int ff)
35 {
36     s[u]=u<=n;vis1[u]=1;
37     for(int to:e2[u])
38         if(to!=ff)
39             dfs1(to,u),s[u]+=s[to];
40 }
41 void dfs2(int u,int ff)
42 {
43     if(ff) res[u]=res[ff]+s[ff]-s[u];vis2[u]=1;
44     if(u<=n){
45         int sum=res[u]+s[u]-1;ans-=sum*2;
46         for(int to:e2[u])
47             if(to!=ff)
48                 ans-=1ll*s[to]*(sum-s[to]);
49     //记得要判定 to!=ff 
50         ans-=1ll*res[u]*(sum-res[u]);
51     }else{
52         int sum=res[u]+s[u];
53         for(int to:e2[u])
54             if(to!=ff)
55                 ans+=1ll*du[u]*s[to]*(sum-s[to]);
56     //记得要判定 to!=ff 
57         ans+=1ll*du[u]*res[u]*(sum-res[u]);
58     }
59     for(int to:e2[u])
60         if(to!=ff) dfs2(to,u);
61     //记得要判定 to!=ff 
62 }
63 int main()
64 {
65     ios::sync_with_stdio(false);
66     cin.tie(0);cout.tie(0);
67     cin>>n>>m;cc=n;
68     for(int i=1,u,v;i<=m;i++)
69     {
70         cin>>u>>v;
71         e1[u].push_back(v);
72         e1[v].push_back(u);
73     }
74     for(int i=1;i<=n;i++)
75         if(!dfn[i]) tarjan(i);
76     for(int i=1;i<=cc;i++)
77         if(!vis1[i])
78             dfs1(i,0);
79     //注意图不连通 
80     for(int i=1;i<=cc;i++)
81         if(!vis2[i])
82             dfs2(i,0);
83     //注意图不连通 
84     cout<<ans<<'\n';
85     return 0;
86 }

四、写题心得:

  好!第一道圆方树的题,很妙,很高兴!收获经验如下:

  $1、彻底了解了建圆方树的过程。=> Exp++!$

  $2、图如果不连通,判定父亲边上点的个数方法有变,如上。=> Exp++! $

  $3、vector\ 好像确实有点慢,链式前向星好快,以后少用\ vector => Exp++$

标签:P4630,cc,题解,APIO2018,back,++,int,low,push
From: https://www.cnblogs.com/yhy-trh/p/P4630.html

相关文章

  • B0626 模拟赛题解
    原题链接前言重庆一位金牌大佬出的。感受:除了最后一题,感觉难度不如C组,甚至没之前D组题难?T1浪费2.5h,最后还是打表秒了。T2想出正解,但发现是数据结构题,最后40min怒打100行,差点打出正解。T3花20min打出20分部分分,赛后发现XD秒了(tql)。T4看题浪费5min......
  • vue3引入bootstrap5的折叠菜单无效问题解决
    问题:通过npm后者yarn安装bootstrap5后,在入口文件全局引入bootstrap5的js、scc,在vue组件引入折叠功能,点击可以正常展开,在点击无法收回解决办法:可参考网上博主的建议,大概意思就是之前引入的js文件不对,导致收回方法没有执行import'bootstrap/dist/js/bootstrap.bundle'main入口......
  • CodeForces 605E Intergalaxy Trips 题解
    题意有一张\(n\)个点的有向完全图,边\(i\toj\)有\(p_{i,j}\)的概率出现(\(p_{i,i}=1\))。你要从\(1\)开始,每天可以走一条出边或留在原地,求最优策略下走到\(n\)的期望天数。输出小数(不取模)。\(n\le10^3\)思路设\(f(i)\)表示从\(i\)走到\(n\)的期望天数,那么......
  • P3387 【模板】缩点 题解
    一、题目描述:给你一个$n$个点,$m$条边的有向图。点带权。求一条路径经过的所有点的权值和最大是多少。点可以重复经过。数据范围:$1\len\le1\times10^4,1\lem\le1\times10^5$。 二、解题思路:缩点板子题,不需要思路。时间复杂度$O(n+m)$。......
  • 复旦大学2022--2023学年第二学期(22级)高等代数II期末考试第八大题解答
    八、(10分) 设$n$阶实方阵$A$满足$A^3=A$,证明: 若对任意的实列向量$x$,均有$x'A'Ax\leqx'x$,则$A$是实对称阵.证法一(几何证法) 将题目转换成几何语言:设$\varphi$是$n$维欧氏空间$V$上的线性算子,满足$\varphi^3=\varphi$,若对$V$中任一向量$v......
  • P3388 【模板】割点(割顶) 题解
    一、题目描述:给你一个$n$个点,$m$条边的无向图。求出所有割点,按节点编号升序排序。数据范围:$1\len\le2\times10^4,1\lem\le1\times10^5$。 二、解题思路:板子题,不需要思路。时间复杂度$O(n+m)$。 三、完整代码:1#include<iostream>......
  • 【问题解决】echart formatter 模板变量 精度
    遇到这样的精度问题这是之前的配置formatter:`{serie|{a}}\n{data|{c}}`+this.label,这样实现了不同样式,出现了jsnumber类型的精度问题formatter也可以返回模板,返回样式|模板的形式formatter:function(data){return(......
  • 缓存与DB数据一致性问题解决的几个思路
    使用缓存必然会碰到缓存跟真实数据不一致的问题,虽然我们会在数据发生变化时通知缓存,但是这个延迟时间内必然会导致数据不一致,如何解决一般有下面几个思路:首先,当这个延迟如果在业务上时可以接受的,比如文章阅读、评论次数这样的缓存数据,这样的问题这里不考虑。 类似数据库分布式事务......
  • docker 安装 jenkins 以及安装插件出现的问题解决方式
    使用docker-composeversion:"3.9"services:jenkins:image:jenkins/jenkins:lts-jdk11ports:-"8080:8080"-"5000:5000"volumes:-/root/software/jenkins/jenkins-data:/var/jenkins_homeenvir......
  • D Odd Queries 题解
    原题传送门题意简述给定一个数组,再给出m个各自独立(即这个操作不影响后续的询问)的询问,每次给定一个区间,询问将这个区间每个元素都修改为k后,数组总和会是奇数吗?解决思路由于n的范围很大,所以暴力肯定是不可以了,由于每个询问是独立的,我们不需要修改序列,所以不需要使用数据结构。......